Exemple #1
0
 public static int ComputeCodedTokenSize(this MetadataReader metadata, int largeRowSize,
                                         TableMask mask)
 {
     return((int)computeCodedTokenSize.Invoke(metadata, new object[] {
         largeRowSize, rowCounts.GetValue(metadata), (ulong)mask
     }
                                              ));
 }
Exemple #2
0
 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;
 }
Exemple #3
0
        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;
        }
Exemple #4
0
 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();
            }
        }
Exemple #7
0
        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.");
            }
        }
Exemple #8
0
        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();
            }
        }