public void HeapSizes() { var heapSizes = new int[][] { new int[] // #US { 0, // Gen0 10, // Gen1 20, // Gen2 30, // Gen3 40, // Gen4 }, new int[] // #String { 0, // Gen0 0, // Gen1 22, // Gen2 22, // Gen3 22, // Gen4 }, new int[] // #Blob { 100, // Gen0 100, // Gen1 100, // Gen2 200, // Gen3 400, // Gen4 }, new int[] // #Guid (sizes are numbers of GUIDs on the heap, not bytes; GUIDs on the heap accumulate, previous content is copied to the next gen). { 1, // Gen0: Guid #1 2, // Gen1: Guid #1, #2 2, // Gen2: Guid #1, #2 2, // Gen3: Guid #1, #2 3, // Gen4: Guid #1, #2, #3 } }; var aggregator = new MetadataAggregator(new RowCounts[0][], heapSizes); TestGenerationHandle(aggregator, MetadataTokens.BlobHandle(99), expectedHandle: MetadataTokens.BlobHandle(99), expectedGeneration: 0); TestGenerationHandle(aggregator, MetadataTokens.BlobHandle(100), expectedHandle: MetadataTokens.BlobHandle(0), expectedGeneration: 3); TestGenerationHandle(aggregator, MetadataTokens.BlobHandle(200), expectedHandle: MetadataTokens.BlobHandle(0), expectedGeneration: 4); TestGenerationHandle(aggregator, MetadataTokens.UserStringHandle(12), expectedHandle: MetadataTokens.UserStringHandle(2), expectedGeneration: 2); TestGenerationHandle(aggregator, MetadataTokens.StringHandle(0), expectedHandle: MetadataTokens.StringHandle(0), expectedGeneration: 2); // GUIDs on the heap accumulate, previous content is copied to the next gen, so the expected handle is the same as the given handle TestGenerationHandle(aggregator, MetadataTokens.GuidHandle(1), expectedHandle: MetadataTokens.GuidHandle(1), expectedGeneration: 0); TestGenerationHandle(aggregator, MetadataTokens.GuidHandle(2), expectedHandle: MetadataTokens.GuidHandle(2), expectedGeneration: 1); TestGenerationHandle(aggregator, MetadataTokens.GuidHandle(3), expectedHandle: MetadataTokens.GuidHandle(3), expectedGeneration: 4); AssertExtensions.Throws <ArgumentException>("handle", () => TestGenerationHandle(aggregator, MetadataTokens.StringHandle(22), expectedHandle: MetadataTokens.StringHandle(0), expectedGeneration: 0)); }
private BlobHandle GetOrAddBlob(ImmutableArray <byte> blob) { if (!_blobs.TryGetValue(blob, out BlobHandle index)) { index = MetadataTokens.BlobHandle(_blobHeapSize); _blobs.Add(blob, index); _blobHeapSize += GetCompressedIntegerLength(blob.Length) + blob.Length; } return(index); }
private void WriteBlobs() { int size = _reader.GetHeapSize(HeapIndex.Blob); if (size == 0) { return; } int[] sizePerKind = new int[(int)BlobKind.Count]; _writer.WriteLine($"#Blob (size = {size}):"); var handle = MetadataTokens.BlobHandle(0); do { byte[] value = _reader.GetBlobBytes(handle); BlobKind kind; string kindString; if (_blobKinds.TryGetValue(handle, out kind)) { kindString = " (" + kind + ")"; // ignoring the compressed blob size: sizePerKind[(int)kind] += value.Length; } else { kindString = ""; } int displayLength = (_options & MetadataVisualizerOptions.ShortenBlobs) != 0 ? Math.Min(4, value.Length) : value.Length; string valueString = BitConverter.ToString(value, 0, displayLength) + (displayLength < value.Length ? "-..." : null); _writer.WriteLine($" {_reader.GetHeapOffset(handle):x}{kindString}: {valueString}"); handle = _reader.GetNextHandle(handle); }while (!handle.IsNil); _writer.WriteLine(); _writer.WriteLine("Sizes:"); for (int i = 0; i < sizePerKind.Length; i++) { if (sizePerKind[i] > 0) { _writer.WriteLine($" {(BlobKind)i}: {(decimal)sizePerKind[i]} bytes"); } } _writer.WriteLine(); }
public BlobHeapTreeNode(PEFile module, MetadataReader metadata) : base(HandleKind.Blob, module, metadata) { list = new List <BlobHeapEntry>(); BlobHandle handle = MetadataTokens.BlobHandle(0); do { BlobHeapEntry entry = new BlobHeapEntry(metadata, handle); list.Add(entry); handle = metadata.GetNextHandle(handle); } while (!handle.IsNil); }
public void HeapSizes() { var heapSizes = new int[][] { new int[] // #US { 0, // Gen0 10, // Gen1 20, // Gen2 30, // Gen3 40, // Gen4 }, new int[] // #String { 0, // Gen0 0, // Gen1 22, // Gen2 22, // Gen3 22, // Gen4 }, new int[] // #Blob { 100, // Gen0 100, // Gen1 100, // Gen2 200, // Gen3 400, // Gen4 }, new int[] // #Guid { 2, // Gen0 4, // Gen1 8, // Gen2 16, // Gen3 32, // Gen4 } }; var aggregator = new MetadataAggregator(new RowCounts[0][], heapSizes); TestGenerationHandle(aggregator, MetadataTokens.BlobHandle(99), expectedHandle: MetadataTokens.BlobHandle(99), expectedGeneration: 0); TestGenerationHandle(aggregator, MetadataTokens.BlobHandle(100), expectedHandle: MetadataTokens.BlobHandle(0), expectedGeneration: 3); TestGenerationHandle(aggregator, MetadataTokens.BlobHandle(200), expectedHandle: MetadataTokens.BlobHandle(0), expectedGeneration: 4); TestGenerationHandle(aggregator, MetadataTokens.UserStringHandle(12), expectedHandle: MetadataTokens.UserStringHandle(2), expectedGeneration: 2); TestGenerationHandle(aggregator, MetadataTokens.StringHandle(0), expectedHandle: MetadataTokens.StringHandle(0), expectedGeneration: 2); AssertExtensions.Throws <ArgumentException>("handle", () => TestGenerationHandle(aggregator, MetadataTokens.StringHandle(22), expectedHandle: MetadataTokens.StringHandle(0), expectedGeneration: 0)); }
public BlobHandle GetBlob(ImmutableArray <byte> blob) { BlobHandle index; if (!_blobs.TryGetValue(blob, out index)) { Debug.Assert(!_streamsAreComplete); index = MetadataTokens.BlobHandle(_blobHeapSize); _blobs.Add(blob, index); _blobHeapSize += BlobWriterImpl.GetCompressedIntegerSize(blob.Length) + blob.Length; } return(index); }
private void WriteBlobs() { int size = reader.GetHeapSize(HeapIndex.Blob); if (size == 0) { return; } writer.WriteLine(string.Format("#Blob (size = {0}):", size)); var handle = MetadataTokens.BlobHandle(0); do { byte[] value = reader.GetBytes(handle); writer.WriteLine(" {0:x}: {1}", reader.GetHeapOffset(handle), BitConverter.ToString(value)); handle = reader.GetNextHandle(handle); }while (!handle.IsNil); writer.WriteLine(); }
public IEnumerable <Blob> GetBlobs() { int size = reader.GetHeapSize(HeapIndex.Blob); if (size == 0) { yield break; } var handle = MetadataTokens.BlobHandle(0); do { byte[] value = reader.GetBlobBytes(handle); yield return(new Blob { Value = value }); handle = reader.GetNextHandle(handle); }while (!handle.IsNil); }
public void SpecificHandleFactories() { Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.MethodDefinitionHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.MethodImplementationHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.MethodSpecificationHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.TypeDefinitionHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.ExportedTypeHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.TypeReferenceHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.TypeSpecificationHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.InterfaceImplementationHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.MemberReferenceHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.FieldDefinitionHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.EventDefinitionHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.PropertyDefinitionHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.StandaloneSignatureHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.ParameterHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.GenericParameterHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.GenericParameterConstraintHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.ModuleReferenceHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.AssemblyReferenceHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.CustomAttributeHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.DeclarativeSecurityAttributeHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.ConstantHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.ManifestResourceHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.AssemblyFileHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.DocumentHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.MethodDebugInformationHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.LocalScopeHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.LocalVariableHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.LocalConstantHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.ImportScopeHandle(1))); Assert.Equal(1, MetadataTokens.GetRowNumber(MetadataTokens.CustomDebugInformationHandle(1))); Assert.Equal(1, MetadataTokens.GetHeapOffset(MetadataTokens.UserStringHandle(1))); Assert.Equal(1, MetadataTokens.GetHeapOffset(MetadataTokens.StringHandle(1))); Assert.Equal(1, MetadataTokens.GetHeapOffset(MetadataTokens.BlobHandle(1))); Assert.Equal(1, MetadataTokens.GetHeapOffset(MetadataTokens.GuidHandle(1))); Assert.Equal(1, MetadataTokens.GetHeapOffset((BlobHandle)MetadataTokens.DocumentNameBlobHandle(1))); }
/// <exception cref="BadImageFormatException">Invalid blob format.</exception> public bool MoveNext() { if (_reader.RemainingBytes == 0) { return(false); } var kind = (ImportDefinitionKind)_reader.ReadByte(); switch (kind) { case ImportDefinitionKind.ImportType: _current = new ImportDefinition( kind, typeOrNamespace: _reader.ReadTypeHandle()); break; case ImportDefinitionKind.ImportNamespace: _current = new ImportDefinition( kind, typeOrNamespace: MetadataTokens.BlobHandle(_reader.ReadCompressedInteger())); break; case ImportDefinitionKind.ImportAssemblyNamespace: _current = new ImportDefinition( kind, assembly: MetadataTokens.AssemblyReferenceHandle(_reader.ReadCompressedInteger()), typeOrNamespace: MetadataTokens.BlobHandle(_reader.ReadCompressedInteger())); break; case ImportDefinitionKind.ImportAssemblyReferenceAlias: _current = new ImportDefinition( kind, alias: MetadataTokens.BlobHandle(_reader.ReadCompressedInteger())); break; case ImportDefinitionKind.AliasAssemblyReference: _current = new ImportDefinition( kind, alias: MetadataTokens.BlobHandle(_reader.ReadCompressedInteger()), assembly: MetadataTokens.AssemblyReferenceHandle(_reader.ReadCompressedInteger())); break; case ImportDefinitionKind.AliasType: _current = new ImportDefinition( kind, alias: MetadataTokens.BlobHandle(_reader.ReadCompressedInteger()), typeOrNamespace: _reader.ReadTypeHandle()); break; case ImportDefinitionKind.ImportXmlNamespace: case ImportDefinitionKind.AliasNamespace: _current = new ImportDefinition( kind, alias: MetadataTokens.BlobHandle(_reader.ReadCompressedInteger()), typeOrNamespace: MetadataTokens.BlobHandle(_reader.ReadCompressedInteger())); break; case ImportDefinitionKind.AliasAssemblyNamespace: _current = new ImportDefinition( kind, alias: MetadataTokens.BlobHandle(_reader.ReadCompressedInteger()), assembly: MetadataTokens.AssemblyReferenceHandle(_reader.ReadCompressedInteger()), typeOrNamespace: MetadataTokens.BlobHandle(_reader.ReadCompressedInteger())); break; default: throw new BadImageFormatException(SR.Format(SR.InvalidImportDefinitionKind, kind)); } return(true); }
public DynamicAnalysisDataReader(byte *buffer, int size) { var reader = new BlobReader(buffer, size); // header: if (reader.ReadByte() != 'D' || reader.ReadByte() != 'A' || reader.ReadByte() != 'M' || reader.ReadByte() != 'D') { throw new BadImageFormatException(); } // version byte major = reader.ReadByte(); byte minor = reader.ReadByte(); if (major != 0 || minor < 1 || minor > 2) { throw new NotSupportedException(); } // table sizes: int documentRowCount = reader.ReadInt32(); int methodSpanRowCount = reader.ReadInt32(); // blob heap sizes: int stringHeapSize = (minor == 1) ? reader.ReadInt32() : 0; int userStringHeapSize = (minor == 1) ? reader.ReadInt32() : 0; int guidHeapSize = reader.ReadInt32(); int blobHeapSize = reader.ReadInt32(); // TODO: check size ranges bool isBlobHeapSmall = blobHeapSize <= ushort.MaxValue; bool isGuidHeapSmall = guidHeapSize / GuidSize <= ushort.MaxValue; var documentsBuilder = ArrayBuilder <DynamicAnalysisDocument> .GetInstance(documentRowCount); for (int i = 0; i < documentRowCount; i++) { var name = MetadataTokens.BlobHandle(ReadReference(ref reader, isBlobHeapSmall)); var hashAlgorithm = MetadataTokens.GuidHandle(ReadReference(ref reader, isGuidHeapSmall)); var hash = MetadataTokens.BlobHandle(ReadReference(ref reader, isBlobHeapSmall)); documentsBuilder.Add(new DynamicAnalysisDocument(name, hashAlgorithm, hash)); } Documents = documentsBuilder.ToImmutableAndFree(); var methodsBuilder = ArrayBuilder <DynamicAnalysisMethod> .GetInstance(methodSpanRowCount); for (int i = 0; i < methodSpanRowCount; i++) { methodsBuilder.Add(new DynamicAnalysisMethod(MetadataTokens.BlobHandle(ReadReference(ref reader, isBlobHeapSmall)))); } Methods = methodsBuilder.ToImmutableAndFree(); int stringHeapOffset = reader.Offset; int userStringHeapOffset = stringHeapOffset + stringHeapSize; int guidHeapOffset = userStringHeapOffset + userStringHeapSize; int blobHeapOffset = guidHeapOffset + guidHeapSize; if (reader.Length != blobHeapOffset + blobHeapSize) { throw new BadImageFormatException(); } _guidHeapBlob = new Blob(buffer + guidHeapOffset, guidHeapSize); _blobHeapBlob = new Blob(buffer + blobHeapOffset, blobHeapSize); }
public void HandleConversionGivesCorrectKind() { var expectedKinds = new SortedSet <HandleKind>((HandleKind[])Enum.GetValues(typeof(HandleKind))); Action <Handle, HandleKind> assert = (handle, expectedKind) => { Assert.False(expectedKinds.Count == 0, "Repeat handle in tests below."); Assert.Equal(expectedKind, handle.Kind); expectedKinds.Remove(expectedKind); }; assert(default(ModuleDefinitionHandle), HandleKind.ModuleDefinition); assert(default(AssemblyDefinitionHandle), HandleKind.AssemblyDefinition); assert(default(InterfaceImplementationHandle), HandleKind.InterfaceImplementation); assert(default(MethodDefinitionHandle), HandleKind.MethodDefinition); assert(default(MethodSpecificationHandle), HandleKind.MethodSpecification); assert(default(TypeDefinitionHandle), HandleKind.TypeDefinition); assert(default(ExportedTypeHandle), HandleKind.ExportedType); assert(default(TypeReferenceHandle), HandleKind.TypeReference); assert(default(TypeSpecificationHandle), HandleKind.TypeSpecification); assert(default(MemberReferenceHandle), HandleKind.MemberReference); assert(default(FieldDefinitionHandle), HandleKind.FieldDefinition); assert(default(EventDefinitionHandle), HandleKind.EventDefinition); assert(default(PropertyDefinitionHandle), HandleKind.PropertyDefinition); assert(default(StandaloneSignatureHandle), HandleKind.StandaloneSignature); assert(default(MemberReferenceHandle), HandleKind.MemberReference); assert(default(FieldDefinitionHandle), HandleKind.FieldDefinition); assert(default(EventDefinitionHandle), HandleKind.EventDefinition); assert(default(PropertyDefinitionHandle), HandleKind.PropertyDefinition); assert(default(StandaloneSignatureHandle), HandleKind.StandaloneSignature); assert(default(ParameterHandle), HandleKind.Parameter); assert(default(GenericParameterHandle), HandleKind.GenericParameter); assert(default(GenericParameterConstraintHandle), HandleKind.GenericParameterConstraint); assert(default(ModuleReferenceHandle), HandleKind.ModuleReference); assert(default(CustomAttributeHandle), HandleKind.CustomAttribute); assert(default(DeclarativeSecurityAttributeHandle), HandleKind.DeclarativeSecurityAttribute); assert(default(ManifestResourceHandle), HandleKind.ManifestResource); assert(default(ConstantHandle), HandleKind.Constant); assert(default(ManifestResourceHandle), HandleKind.ManifestResource); assert(default(AssemblyFileHandle), HandleKind.AssemblyFile); assert(default(MethodImplementationHandle), HandleKind.MethodImplementation); assert(default(AssemblyFileHandle), HandleKind.AssemblyFile); // Bug #: DevDiv: Bug 1048345: [System.Reflection.Metada] For select handles, default(THandle) does not preserve type. // Not changing this immediately, because it has been this way for a long time so need to check Roslyn compat. // //assertEqual(default(StringHandle), HandleKind.String); //assertEqual(default(AssemblyReferenceHandle), HandleKind.AssemblyReference); //assertEqual(default(UserStringHandle), HandleKind.UserString); //assertEqual(default(GuidHandle), HandleKind.Guid); //assertEqual(default(BlobHandle), HandleKind.Blob); //assertEqual(default(NamespaceDefinitionHandle), HandleKind.NamespaceDefinition); // In the meantime, check using initialized handles behave as expected assert(MetadataTokens.StringHandle(1), HandleKind.String); assert(MetadataTokens.AssemblyReferenceHandle(1), HandleKind.AssemblyReference); assert(MetadataTokens.UserStringHandle(1), HandleKind.UserString); assert(MetadataTokens.GuidHandle(1), HandleKind.Guid); assert(MetadataTokens.BlobHandle(1), HandleKind.Blob); assert(NamespaceDefinitionHandle.FromIndexOfFullName(1), HandleKind.NamespaceDefinition); Assert.True(expectedKinds.Count == 0, "Some handles are missing from this test: " + String.Join(",\r\n", expectedKinds)); }
private void WriteBlobs() { int size = _reader.GetHeapSize(HeapIndex.Blob); if (size == 0) { return; } int[] sizePerKind = new int[(int)BlobKind.Count]; _writer.WriteLine($"#Blob (size = {size}):"); var handle = MetadataTokens.BlobHandle(0); do { byte[] value = _reader.GetBlobBytes(handle); BlobKind kind; string kindString; if (_blobKinds.TryGetValue(handle, out kind)) { kindString = " (" + kind + ")"; // ignoring the compressed blob size: sizePerKind[(int)kind] += value.Length; } else { kindString = ""; } int displayLength = (_options & MetadataVisualizerOptions.ShortenBlobs) != 0 ? Math.Min(4, value.Length) : value.Length; string valueString = BitConverter.ToString(value, 0, displayLength) + (displayLength < value.Length ? "-..." : null); _writer.WriteLine($" {_reader.GetHeapOffset(handle):x}{kindString}: {valueString}"); handle = _reader.GetNextHandle(handle); }while (!handle.IsNil); _writer.WriteLine(); _writer.WriteLine("Sizes:"); for (int i = 0; i < sizePerKind.Length; i++) { if (sizePerKind[i] > 0) { _writer.WriteLine($" {(BlobKind)i}: {(decimal)sizePerKind[i]} bytes"); } } // don't calculate statistics for EnC delta, it's not interesting if (_aggregator == null) { _writer.WriteLine(); _writer.WriteLine("CustomAttribute sizes by constructor:"); foreach (var grouping in from caHandle in _reader.CustomAttributes let ca = _reader.GetCustomAttribute(caHandle) group ca.Constructor by ca.Value into values // blob -> { ctor1, ctor2, ... } group values.Key by values.First() into g // ctor1 -> { blob1, ... } select new { Ctor = g.Key, Size = g.Sum(ca => _reader.GetBlobReader(ca).Length) } into ctorAndSize orderby ctorAndSize.Size descending select ctorAndSize) { string typeStr = null; switch (grouping.Ctor.Kind) { case HandleKind.MemberReference: var memberRef = _reader.GetMemberReference((MemberReferenceHandle)grouping.Ctor); switch (memberRef.Parent.Kind) { case HandleKind.TypeReference: var typeRef = _reader.GetTypeReference((TypeReferenceHandle)memberRef.Parent); typeStr = typeRef.Namespace.IsNil ? _reader.GetString(typeRef.Name) : _reader.GetString(typeRef.Namespace) + "." + _reader.GetString(typeRef.Name); break; case HandleKind.TypeDefinition: var typeDef = _reader.GetTypeDefinition((TypeDefinitionHandle)memberRef.Parent); typeStr = typeDef.Namespace.IsNil ? _reader.GetString(typeDef.Name) : _reader.GetString(typeDef.Namespace) + "." + _reader.GetString(typeDef.Name); break; case HandleKind.MethodDefinition: case HandleKind.ModuleReference: case HandleKind.TypeSpecification: break; } break; case HandleKind.MethodDefinition: // TODO break; } // grouping.Key _writer.WriteLine($" {typeStr ?? Token(grouping.Ctor)}: {grouping.Size} bytes"); } _writer.WriteLine(); } }
public unsafe FieldMarshal(byte *ptr, int blobHeapSize, int hasFieldMarshalRefSize) { Parent = Helpers.FromHasFieldMarshalTag((uint)Helpers.GetValue(ptr, hasFieldMarshalRefSize)); NativeType = MetadataTokens.BlobHandle(Helpers.GetValue(ptr + hasFieldMarshalRefSize, blobHeapSize)); }