public static int ComputeCodedTokenSize(this MetadataReader metadata, int largeRowSize, TableMask mask) { return((int)computeCodedTokenSize.Invoke(metadata, new object[] { largeRowSize, rowCounts.GetValue(metadata), (ulong)mask } )); }
private static int ComputeCodedTokenSize(int largeRowSize, int[] rowCountArray, TableMask tablesReferenced) { bool isAllReferencedTablesSmall = true; ulong tablesReferencedMask = (ulong)tablesReferenced; for (int tableIndex = 0; tableIndex < TableCount; tableIndex++) { if ((tablesReferencedMask & 0x0000000000000001UL) != 0) { isAllReferencedTablesSmall &= (rowCountArray[tableIndex] < largeRowSize); } tablesReferencedMask >>= 1; } return isAllReferencedTablesSmall ? 2 : 4; }
private int ComputeCodedTokenSize(uint largeRowSize, uint[] rowCountArray, TableMask tablesReferenced) { if (IsMinimalDelta) { return LargeIndexSize; } bool isAllReferencedTablesSmall = true; ulong tablesReferencedMask = (ulong)tablesReferenced; for (int tableIndex = 0; tableIndex < TableIndexExtensions.Count; tableIndex++) { if ((tablesReferencedMask & 1UL) != 0) { isAllReferencedTablesSmall = isAllReferencedTablesSmall && (rowCountArray[tableIndex] < largeRowSize); } tablesReferencedMask >>= 1; } return isAllReferencedTablesSmall ? SmallIndexSize : LargeIndexSize; }
private bool IsDeclaredSorted(TableMask index) { return (this.MetadataTableHeader.SortedTables & index) != 0; }
private bool IsDeclaredSorted(TableMask index) { return (_sortedTables & index) != 0; }
private void ReadMetadataTableHeader(ref BlobReader reader, out HeapSizes heapSizes, out int[] metadataTableRowCounts, out TableMask sortedTables) { if (reader.RemainingBytes < MetadataStreamConstants.SizeOfMetadataTableHeader) { throw new BadImageFormatException(SR.MetadataTableHeaderTooSmall); } // reserved (shall be ignored): reader.ReadUInt32(); // major version (shall be ignored): reader.ReadByte(); // minor version (shall be ignored): reader.ReadByte(); // heap sizes: heapSizes = (HeapSizes)reader.ReadByte(); // reserved (shall be ignored): reader.ReadByte(); ulong presentTables = reader.ReadUInt64(); sortedTables = (TableMask)reader.ReadUInt64(); // According to ECMA-335, MajorVersion and MinorVersion have fixed values and, // based on recommendation in 24.1 Fixed fields: When writing these fields it // is best that they be set to the value indicated, on reading they should be ignored. // We will not be checking version values. We will continue checking that the set of // present tables is within the set we understand. ulong validTables = (ulong)(TableMask.TypeSystemTables | TableMask.DebugTables); if ((presentTables & ~validTables) != 0) { throw new BadImageFormatException(SR.Format(SR.UnknownTables, presentTables)); } if (_metadataStreamKind == MetadataStreamKind.Compressed) { // In general Ptr tables and EnC tables are not allowed in a compressed stream. // However when asked for a snapshot of the current metadata after an EnC change has been applied // the CLR includes the EnCLog table into the snapshot. We need to be able to read the image, // so we'll allow the table here but pretend it's empty later. if ((presentTables & (ulong)(TableMask.PtrTables | TableMask.EnCMap)) != 0) { throw new BadImageFormatException(SR.IllegalTablesInCompressedMetadataStream); } } metadataTableRowCounts = ReadMetadataTableRowCounts(ref reader, presentTables); if ((heapSizes & HeapSizes.ExtraData) == HeapSizes.ExtraData) { // Skip "extra data" used by some obfuscators. Although it is not mentioned in the CLI spec, // it is honored by the native metadata reader. reader.ReadUInt32(); } }
public void ValidateTagToTokenConversion() { foreach (var tag in GetTags()) { Assert.True((1 << tag.GetNumberOfBits()) <= tag.GetTagToTokenTypeArray().Length, tag.Name + " has mismatch between NumberOfBits and TagToTokenTypeArray.Length"); Assert.True(tag.GetTagMask() == (1 << tag.GetNumberOfBits()) - 1, tag.Name + " has mismatch between NumberOfBits and TagMask"); TableMask tablesNotUsed = tag.GetTablesReferenced(); Assert.True(tablesNotUsed != 0, tag.Name + " does not have anything in TablesReferenced."); int badTagCount = 0; Random random = new Random(42); for (uint i = 0, n = (uint)(1 << tag.GetNumberOfBits()); i < n; i++) { uint rowId = (uint)random.Next(((int)TokenTypeIds.RIDMask + 1)); uint codedIndex = i | (rowId << tag.GetNumberOfBits()); EntityHandle handle; try { handle = tag.ConvertToHandle(codedIndex); } catch (BadImageFormatException) { badTagCount++; continue; } Assert.True(handle.RowId == rowId, tag.Name + " did not return correct row id."); uint badRowId = (uint)random.Next((int)TokenTypeIds.RIDMask + 1, int.MaxValue); Assert.Throws <BadImageFormatException>(() => tag.ConvertToHandle(i | ~tag.GetTagMask())); Assert.Throws <BadImageFormatException>(() => tag.ConvertToHandle(i | ((TokenTypeIds.RIDMask + 1) << tag.GetNumberOfBits()))); Assert.Throws <BadImageFormatException>(() => tag.ConvertToHandle(i | (badRowId << tag.GetNumberOfBits()))); Assert.True((uint)(handle.Kind) << 24 == tag.GetTagToTokenTypeArray()[i], tag.Name + " did not return handle type matching its TagToTokenTypeArray or TagToTokenTypeByteVector"); TableMask handleTableMask = (TableMask)(1UL << (int)handle.Kind); Assert.True(tag.GetTagValue(handleTableMask.ToString()) == i, tag.Name + " does not have a constant for '" + handleTableMask.ToString() + "' with matching value: " + i); Assert.True((tag.GetTablesReferenced() & handleTableMask) == handleTableMask, tag.Name + " does not declare that it references '" + handleTableMask.ToString() + "' table."); TableMask tablesNotUsedPreviously = tablesNotUsed; tablesNotUsed &= ~handleTableMask; Assert.True(handleTableMask == 0 || tablesNotUsedPreviously != tablesNotUsed, tag.Name + " did not use any table for tag value: " + i); uint?roundTripped = tag.ConvertToTag(handle); Assert.True(roundTripped == null || roundTripped == codedIndex, tag.Name + " did not round trip coded index -> handle -> coded index"); } Assert.True(badTagCount == (1 << tag.GetNumberOfBits()) - BitArithmetic.CountBits((ulong)tag.GetTablesReferenced()), tag.Name + " did not find the correct number of bad tags."); Assert.True(tablesNotUsed == 0, tag.Name + " did not use all of TablesReferenced when passed all possible tag bits up to NumberOfBits."); } }
private void ReadMetadataTableHeader(ref BlobReader reader, out HeapSizes heapSizes, out int[] metadataTableRowCounts, out TableMask sortedTables) { if (reader.RemainingBytes < MetadataStreamConstants.SizeOfMetadataTableHeader) { throw new BadImageFormatException("MetadataTableHeaderTooSmall"); } // reserved (shall be ignored): reader.ReadUInt32(); // major version (shall be ignored): reader.ReadByte(); // minor version (shall be ignored): reader.ReadByte(); // heap sizes: heapSizes = (HeapSizes)reader.ReadByte(); // reserved (shall be ignored): reader.ReadByte(); ulong presentTables = reader.ReadUInt64(); sortedTables = (TableMask)reader.ReadUInt64(); // According to ECMA-335, MajorVersion and MinorVersion have fixed values and, // based on recommendation in 24.1 Fixed fields: When writing these fields it // is best that they be set to the value indicated, on reading they should be ignored. // We will not be checking version values. We will continue checking that the set of // present tables is within the set we understand. ulong validTables = (ulong)(TableMask.TypeSystemTables | TableMask.DebugTables); if ((presentTables & ~validTables) != 0) { throw new BadImageFormatException("UnknownTables"); } if (_metadataStreamKind == MetadataStreamKind.Compressed) { // In general Ptr tables and EnC tables are not allowed in a compressed stream. // However when asked for a snapshot of the current metadata after an EnC change has been applied // the CLR includes the EnCLog table into the snapshot. We need to be able to read the image, // so we'll allow the table here but pretend it's empty later. if ((presentTables & (ulong)(TableMask.PtrTables | TableMask.EnCMap)) != 0) { throw new BadImageFormatException("IllegalTablesInCompressedMetadataStream"); } } metadataTableRowCounts = ReadMetadataTableRowCounts(ref reader, presentTables); if ((heapSizes & HeapSizes.ExtraData) == HeapSizes.ExtraData) { // Skip "extra data" used by some obfuscators. Although it is not mentioned in the CLI spec, // it is honored by the native metadata reader. reader.ReadUInt32(); } }