コード例 #1
0
ファイル: MetadataReader.cs プロジェクト: dox0/DotNet471RS3
        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();
            }
        }
コード例 #2
0
ファイル: MethodBodyBlock.cs プロジェクト: pgovind/runtime
        private static ImmutableArray <ExceptionRegion> ReadSmallExceptionHandlers(ref BlobReader memReader, int count)
        {
            var result = new ExceptionRegion[count];

            for (int i = 0; i < result.Length; i++)
            {
                var kind                     = (ExceptionRegionKind)memReader.ReadUInt16();
                var tryOffset                = memReader.ReadUInt16();
                var tryLength                = memReader.ReadByte();
                var handlerOffset            = memReader.ReadUInt16();
                var handlerLength            = memReader.ReadByte();
                var classTokenOrFilterOffset = memReader.ReadInt32();
                result[i] = new ExceptionRegion(kind, tryOffset, tryLength, handlerOffset, handlerLength, classTokenOrFilterOffset);
            }

            return(ImmutableArray.Create(result));
        }
コード例 #3
0
ファイル: ILReader.cs プロジェクト: airbrush/CSD
        public static ILResult GetInstructions(BlobReader reader)
        {
            var instructions = ImmutableArray.CreateBuilder<Instruction>();
            List<int[]> switches = null;

            while (reader.RemainingBytes > 0)
            {
                ushort pos = (ushort)reader.Offset;
                byte op0 = reader.ReadByte();
                InstrCode code = (InstrCode)(op0 == 0xFE ? unchecked(0xFE00 + reader.ReadByte()) : op0);
                OperandType opType = code.GetOperandType();

                ulong operand = 0;
                if (code == InstrCode.Switch)
                {
                    if (switches == null)
                        switches = new List<int[]>();

                    operand = (ulong)switches.Count;
                    uint branchCount = reader.ReadUInt32();
                    int[] branches = new int[branchCount];
                    for (int i = 0; i < branchCount; i++)
                    {
                        branches[i] = reader.ReadInt32();
                    }
                    switches.Add(branches);
                }
                else
                {
                    byte operandSize = opType.GetOperandSize();
                    operand = operandSize == 8 ? reader.ReadUInt64()
                        : operandSize == 4 ? reader.ReadUInt32()
                        : operandSize == 2 ? reader.ReadUInt16()
                        : operandSize == 1 ? (ulong)reader.ReadByte()
                        : 0;
                }

                instructions.Add(new Instruction(pos, code, opType, operand));
            }

            return new ILResult
            {
                Instructions = instructions.ToImmutable(),
                Switches = switches?.ToArray()
            };
        }
コード例 #4
0
        private unsafe static ImmutableArray<LocalSlotDebugInfo> UncompressSlotMap(ImmutableArray<byte> compressedSlotMap)
        {
            if (compressedSlotMap.IsDefaultOrEmpty)
            {
                return default(ImmutableArray<LocalSlotDebugInfo>);
            }

            var mapBuilder = ArrayBuilder<LocalSlotDebugInfo>.GetInstance();
            int syntaxOffsetBaseline = -1;

            fixed (byte* compressedSlotMapPtr = &compressedSlotMap.ToArray()[0])
            {
                var blobReader = new BlobReader(compressedSlotMapPtr, compressedSlotMap.Length);
                while (blobReader.RemainingBytes > 0)
                {
                    byte b = blobReader.ReadByte();

                    if (b == SyntaxOffsetBaseline)
                    {
                        syntaxOffsetBaseline = -blobReader.ReadCompressedInteger();
                        continue;
                    }

                    if (b == 0)
                    {
                        // short-lived temp, no info
                        mapBuilder.Add(new LocalSlotDebugInfo(SynthesizedLocalKind.LoweringTemp, default(LocalDebugId)));
                        continue;
                    }

                    var kind = (SynthesizedLocalKind)((b & 0x3f) - 1);
                    bool hasOrdinal = (b & (1 << 7)) != 0;

                    int syntaxOffset;
                    if (!blobReader.TryReadCompressedInteger(out syntaxOffset))
                    {
                        // invalid data
                        return default(ImmutableArray<LocalSlotDebugInfo>);
                    }

                    syntaxOffset += syntaxOffsetBaseline;

                    int ordinal = 0;
                    if (hasOrdinal && !blobReader.TryReadCompressedInteger(out ordinal))
                    {
                        // invalid data
                        return default(ImmutableArray<LocalSlotDebugInfo>);
                    }

                    mapBuilder.Add(new LocalSlotDebugInfo(kind, new LocalDebugId(syntaxOffset, ordinal)));
                }
            }

            return mapBuilder.ToImmutableAndFree();
        }
コード例 #5
0
        /// <summary>
        /// We want to know if a given method implements a redirected interface.
        /// For example, if we are given the method RemoveAt on a class "A"
        /// which implements the IVector interface (which is redirected
        /// to IList in .NET) then this method would return true. The most
        /// likely reason why we would want to know this is that we wish to hide
        /// (mark private) all methods which implement methods on a redirected
        /// interface.
        /// </summary>
        /// <param name="memberRef">The declaration token for the method</param>
        /// <param name="isIDisposable">
        /// Returns true if the redirected interface is <see cref="IDisposable"/>.
        /// </param>
        /// <returns>True if the method implements a method on a redirected interface.
        /// False otherwise.</returns>
        private bool ImplementsRedirectedInterface(MemberReferenceHandle memberRef, out bool isIDisposable)
        {
            isIDisposable = false;

            EntityHandle parent = MemberRefTable.GetClass(memberRef);

            TypeReferenceHandle typeRef;

            if (parent.Kind == HandleKind.TypeReference)
            {
                typeRef = (TypeReferenceHandle)parent;
            }
            else if (parent.Kind == HandleKind.TypeSpecification)
            {
                BlobHandle blob = TypeSpecTable.GetSignature((TypeSpecificationHandle)parent);
                BlobReader sig  = new BlobReader(BlobStream.GetMemoryBlock(blob));

                if (sig.Length < 2 ||
                    sig.ReadByte() != (byte)CorElementType.ELEMENT_TYPE_GENERICINST ||
                    sig.ReadByte() != (byte)CorElementType.ELEMENT_TYPE_CLASS)
                {
                    return(false);
                }

                EntityHandle token = sig.ReadTypeHandle();
                if (token.Kind != HandleKind.TypeReference)
                {
                    return(false);
                }

                typeRef = (TypeReferenceHandle)token;
            }
            else
            {
                return(false);
            }

            return(GetProjectionIndexForTypeReference(typeRef, out isIDisposable) >= 0);
        }
コード例 #6
0
        public static MethodBodyBlock Create(BlobReader reader)
        {
            int startOffset = reader.Offset;
            int ilSize;

            // Error need to check if the Memory Block is empty. This is calse for all the calls...
            byte headByte = reader.ReadByte();
            if ((headByte & ILFormatMask) == ILTinyFormat)
            {
                // tiny IL can't have locals so technically this shouldn't matter,
                // but false is consistent with other metadata readers and helps
                // for use cases involving comparing our output with theirs.
                const bool initLocalsForTinyIL = false;

                ilSize = headByte >> ILTinyFormatSizeShift;
                return new MethodBodyBlock(
                    initLocalsForTinyIL,
                    8,
                    default(StandaloneSignatureHandle),
                    reader.GetMemoryBlockAt(0, ilSize),
                    ImmutableArray<ExceptionRegion>.Empty,
                    1 + ilSize // header + IL
                );
            }

            if ((headByte & ILFormatMask) != ILFatFormat)
            {
                throw new BadImageFormatException(string.Format(MetadataResources.InvalidMethodHeader1, headByte));
            }

            // FatILFormat
            byte headByte2 = reader.ReadByte();
            if ((headByte2 >> ILFatFormatHeaderSizeShift) != ILFatFormatHeaderSize)
            {
                throw new BadImageFormatException(string.Format(MetadataResources.InvalidMethodHeader2, headByte, headByte2));
            }

            bool localsInitialized = (headByte & ILInitLocals) == ILInitLocals;
            bool hasExceptionHandlers = (headByte & ILMoreSects) == ILMoreSects;

            ushort maxStack = reader.ReadUInt16();
            ilSize = reader.ReadInt32();

            int localSignatureToken = reader.ReadInt32();
            StandaloneSignatureHandle localSignatureHandle;
            if (localSignatureToken == 0)
            {
                localSignatureHandle = default(StandaloneSignatureHandle);
            }
            else if ((localSignatureToken & TokenTypeIds.TokenTypeMask) == TokenTypeIds.Signature)
            {
                localSignatureHandle = StandaloneSignatureHandle.FromRowId((uint)localSignatureToken & TokenTypeIds.RIDMask);
            }
            else
            {
                throw new BadImageFormatException(string.Format(MetadataResources.InvalidLocalSignatureToken, unchecked((uint)localSignatureToken)));
            }

            var ilBlock = reader.GetMemoryBlockAt(0, ilSize);
            reader.SkipBytes(ilSize);

            ImmutableArray<ExceptionRegion> exceptionHandlers;
            if (hasExceptionHandlers)
            {
                reader.Align(4);
                byte sehHeader = reader.ReadByte();
                if ((sehHeader & SectEHTable) != SectEHTable)
                {
                    throw new BadImageFormatException(string.Format(MetadataResources.InvalidSehHeader, sehHeader));
                }

                bool sehFatFormat = (sehHeader & SectFatFormat) == SectFatFormat;
                int dataSize = reader.ReadByte();
                if (sehFatFormat)
                {
                    dataSize += reader.ReadUInt16() << 8;
                    exceptionHandlers = ReadFatExceptionHandlers(ref reader, dataSize / 24);
                }
                else
                {
                    reader.SkipBytes(2); // skip over reserved field
                    exceptionHandlers = ReadSmallExceptionHandlers(ref reader, dataSize / 12);
                }
            }
            else
            {
                exceptionHandlers = ImmutableArray<ExceptionRegion>.Empty;
            }

            return new MethodBodyBlock(
                localsInitialized,
                maxStack,
                localSignatureHandle,
                ilBlock,
                exceptionHandlers,
                reader.Offset - startOffset);
        }
コード例 #7
0
        IAttribute ConvertMarshalInfo(SRM.BlobReader marshalInfo)
        {
            var   b = new AttributeBuilder(module, KnownAttribute.MarshalAs);
            IType unmanagedTypeType = module.Compilation.FindType(new TopLevelTypeName(InteropServices, nameof(UnmanagedType)));

            int type = marshalInfo.ReadByte();

            b.AddFixedArg(unmanagedTypeType, type);

            int size;

            switch (type)
            {
            case 0x1e:                     // FixedArray
                if (!marshalInfo.TryReadCompressedInteger(out size))
                {
                    size = 0;
                }
                b.AddNamedArg("SizeConst", KnownTypeCode.Int32, size);
                if (marshalInfo.RemainingBytes > 0)
                {
                    type = marshalInfo.ReadByte();
                    if (type != 0x66)                             // None
                    {
                        b.AddNamedArg("ArraySubType", unmanagedTypeType, type);
                    }
                }
                break;

            case 0x1d:                     // SafeArray
                if (marshalInfo.RemainingBytes > 0)
                {
                    VarEnum varType = (VarEnum)marshalInfo.ReadByte();
                    if (varType != VarEnum.VT_EMPTY)
                    {
                        var varEnumType = new TopLevelTypeName(InteropServices, nameof(VarEnum));
                        b.AddNamedArg("SafeArraySubType", varEnumType, (int)varType);
                    }
                }
                break;

            case 0x2a:                     // NATIVE_TYPE_ARRAY
                if (marshalInfo.RemainingBytes > 0)
                {
                    type = marshalInfo.ReadByte();
                }
                else
                {
                    type = 0x66;                            // Cecil uses NativeType.None as default.
                }
                if (type != 0x50)                           // Max
                {
                    b.AddNamedArg("ArraySubType", unmanagedTypeType, type);
                }
                int sizeParameterIndex = marshalInfo.TryReadCompressedInteger(out int value) ? value : -1;
                size = marshalInfo.TryReadCompressedInteger(out value) ? value : -1;
                int sizeParameterMultiplier = marshalInfo.TryReadCompressedInteger(out value) ? value : -1;
                if (size >= 0)
                {
                    b.AddNamedArg("SizeConst", KnownTypeCode.Int32, size);
                }
                if (sizeParameterMultiplier != 0 && sizeParameterIndex >= 0)
                {
                    b.AddNamedArg("SizeParamIndex", KnownTypeCode.Int16, (short)sizeParameterIndex);
                }
                break;

            case 0x2c:                     // CustomMarshaler
                string guidValue     = marshalInfo.ReadSerializedString();
                string unmanagedType = marshalInfo.ReadSerializedString();
                string managedType   = marshalInfo.ReadSerializedString();
                string cookie        = marshalInfo.ReadSerializedString();
                if (managedType != null)
                {
                    b.AddNamedArg("MarshalType", KnownTypeCode.String, managedType);
                }
                if (!string.IsNullOrEmpty(cookie))
                {
                    b.AddNamedArg("MarshalCookie", KnownTypeCode.String, cookie);
                }
                break;

            case 0x17:                     // FixedSysString
                b.AddNamedArg("SizeConst", KnownTypeCode.Int32, marshalInfo.ReadCompressedInteger());
                break;
            }

            return(b.Build());
        }
コード例 #8
0
        private void ReadMetadataTableHeader(ref BlobReader memReader, out uint[] metadataTableRowCounts)
        {
            if (memReader.RemainingBytes < MetadataStreamConstants.SizeOfMetadataTableHeader)
            {
                throw new BadImageFormatException(MetadataResources.MetadataTableHeaderTooSmall);
            }

            this.MetadataTableHeader.Reserved = memReader.ReadUInt32();
            this.MetadataTableHeader.MajorVersion = memReader.ReadByte();
            this.MetadataTableHeader.MinorVersion = memReader.ReadByte();
            this.MetadataTableHeader.HeapSizeFlags = (HeapSizeFlag)memReader.ReadByte();
            this.MetadataTableHeader.RowId = memReader.ReadByte();
            this.MetadataTableHeader.ValidTables = (TableMask)memReader.ReadUInt64();
            this.MetadataTableHeader.SortedTables = (TableMask)memReader.ReadUInt64();
            ulong presentTables = (ulong)this.MetadataTableHeader.ValidTables;

            // 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.V2_0_TablesMask;

            if ((presentTables & ~validTables) != 0)
            {
                throw new BadImageFormatException(string.Format(MetadataResources.UnknownTables, presentTables));
            }

            if (this.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(MetadataResources.IllegalTablesInCompressedMetadataStream);
                }
            }

            int numberOfTables = this.MetadataTableHeader.GetNumberOfTablesPresent();
            if (memReader.RemainingBytes < numberOfTables * sizeof(int))
            {
                throw new BadImageFormatException(MetadataResources.TableRowCountSpaceTooSmall);
            }

            var rowCounts = new uint[numberOfTables];
            for (int i = 0; i < rowCounts.Length; i++)
            {
                rowCounts[i] = memReader.ReadUInt32();
            }

            metadataTableRowCounts = rowCounts;
        }
コード例 #9
0
ファイル: PEReader.cs プロジェクト: AndreGleichner/corefx
        /// <summary>
        /// Reads the data pointed to by the specified Debug Directory entry and interprets them as CodeView.
        /// </summary>
        /// <exception cref="ArgumentException"><paramref name="entry"/> is not a CodeView entry.</exception>
        /// <exception cref="BadImageFormatException">Bad format of the data.</exception>
        /// <exception cref="IOException">IO error while reading from the underlying stream.</exception>
        public unsafe CodeViewDebugDirectoryData ReadCodeViewDebugDirectoryData(DebugDirectoryEntry entry)
        {
            if (entry.Type != DebugDirectoryEntryType.CodeView)
            {
                throw new ArgumentException(SR.NotCodeViewEntry, nameof(entry));
            }

            using (AbstractMemoryBlock block = _peImage.GetMemoryBlock(entry.DataPointer, entry.DataSize))
            {
                var reader = new BlobReader(block.Pointer, block.Size);

                if (reader.ReadByte() != (byte)'R' ||
                    reader.ReadByte() != (byte)'S' ||
                    reader.ReadByte() != (byte)'D' ||
                    reader.ReadByte() != (byte)'S')
                {
                    throw new BadImageFormatException(SR.UnexpectedCodeViewDataSignature);
                }

                Guid guid = reader.ReadGuid();
                int age = reader.ReadInt32();
                string path = reader.ReadUtf8NullTerminated();

                // path may be padded with NULs
                while (reader.RemainingBytes > 0)
                {
                    if (reader.ReadByte() != 0)
                    {
                        throw new BadImageFormatException(SR.InvalidPathPadding);
                    }
                }

                return new CodeViewDebugDirectoryData(guid, age, path);
            }
        }
コード例 #10
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();
            }
        }
コード例 #11
0
        /// <exception cref="InvalidDataException">Invalid data.</exception>
        private unsafe static ImmutableArray<LocalSlotDebugInfo> UncompressSlotMap(ImmutableArray<byte> compressedSlotMap)
        {
            if (compressedSlotMap.IsDefaultOrEmpty)
            {
                return default(ImmutableArray<LocalSlotDebugInfo>);
            }

            var mapBuilder = ArrayBuilder<LocalSlotDebugInfo>.GetInstance();
            int syntaxOffsetBaseline = -1;

            fixed (byte* compressedSlotMapPtr = &compressedSlotMap.ToArray()[0])
            {
                var blobReader = new BlobReader(compressedSlotMapPtr, compressedSlotMap.Length);
                while (blobReader.RemainingBytes > 0)
                {
                    try
                    {
                        // Note: integer operations below can't overflow since compressed integers are in range [0, 0x20000000)

                        byte b = blobReader.ReadByte();

                        if (b == SyntaxOffsetBaseline)
                        {
                            syntaxOffsetBaseline = -blobReader.ReadCompressedInteger();
                            continue;
                        }

                        if (b == 0)
                        {
                            // short-lived temp, no info
                            mapBuilder.Add(new LocalSlotDebugInfo(SynthesizedLocalKind.LoweringTemp, default(LocalDebugId)));
                            continue;
                        }

                        var kind = (SynthesizedLocalKind)((b & 0x3f) - 1);
                        bool hasOrdinal = (b & (1 << 7)) != 0;

                        int syntaxOffset = blobReader.ReadCompressedInteger() + syntaxOffsetBaseline;

                        int ordinal = hasOrdinal ? blobReader.ReadCompressedInteger() : 0;

                        mapBuilder.Add(new LocalSlotDebugInfo(kind, new LocalDebugId(syntaxOffset, ordinal)));
                    }
                    catch (BadImageFormatException)
                    {
                        throw CreateInvalidDataException(compressedSlotMap, blobReader.Offset);
                    }
                }
            }

            return mapBuilder.ToImmutableAndFree();
        }
コード例 #12
0
ファイル: MethodBodyBlock.cs プロジェクト: pgovind/runtime
        public static MethodBodyBlock Create(BlobReader reader)
        {
            int startOffset = reader.Offset;
            int ilSize;

            // Error need to check if the Memory Block is empty. This is false for all the calls...
            byte headByte = reader.ReadByte();

            if ((headByte & ILFormatMask) == ILTinyFormat)
            {
                // tiny IL can't have locals so technically this shouldn't matter,
                // but false is consistent with other metadata readers and helps
                // for use cases involving comparing our output with theirs.
                const bool initLocalsForTinyIL = false;

                ilSize = headByte >> ILTinyFormatSizeShift;
                return(new MethodBodyBlock(
                           initLocalsForTinyIL,
                           8,
                           default(StandaloneSignatureHandle),
                           reader.GetMemoryBlockAt(0, ilSize),
                           ImmutableArray <ExceptionRegion> .Empty,
                           1 + ilSize // header + IL
                           ));
            }

            if ((headByte & ILFormatMask) != ILFatFormat)
            {
                throw new BadImageFormatException(SR.Format(SR.InvalidMethodHeader1, headByte));
            }

            // FatILFormat
            byte headByte2 = reader.ReadByte();

            if ((headByte2 >> ILFatFormatHeaderSizeShift) != ILFatFormatHeaderSize)
            {
                throw new BadImageFormatException(SR.Format(SR.InvalidMethodHeader2, headByte, headByte2));
            }

            bool localsInitialized    = (headByte & ILInitLocals) == ILInitLocals;
            bool hasExceptionHandlers = (headByte & ILMoreSects) == ILMoreSects;

            ushort maxStack = reader.ReadUInt16();

            ilSize = reader.ReadInt32();

            int localSignatureToken = reader.ReadInt32();
            StandaloneSignatureHandle localSignatureHandle;

            if (localSignatureToken == 0)
            {
                localSignatureHandle = default(StandaloneSignatureHandle);
            }
            else if ((localSignatureToken & TokenTypeIds.TypeMask) == TokenTypeIds.Signature)
            {
                localSignatureHandle = StandaloneSignatureHandle.FromRowId((int)((uint)localSignatureToken & TokenTypeIds.RIDMask));
            }
            else
            {
                throw new BadImageFormatException(SR.Format(SR.InvalidLocalSignatureToken, unchecked ((uint)localSignatureToken)));
            }

            var ilBlock = reader.GetMemoryBlockAt(0, ilSize);

            reader.Offset += ilSize;

            ImmutableArray <ExceptionRegion> exceptionHandlers;

            if (hasExceptionHandlers)
            {
                reader.Align(4);
                byte sehHeader = reader.ReadByte();
                if ((sehHeader & SectEHTable) != SectEHTable)
                {
                    throw new BadImageFormatException(SR.Format(SR.InvalidSehHeader, sehHeader));
                }

                bool sehFatFormat = (sehHeader & SectFatFormat) == SectFatFormat;
                int  dataSize     = reader.ReadByte();
                if (sehFatFormat)
                {
                    dataSize         += reader.ReadUInt16() << 8;
                    exceptionHandlers = ReadFatExceptionHandlers(ref reader, dataSize / 24);
                }
                else
                {
                    reader.Offset    += 2; // skip over reserved field
                    exceptionHandlers = ReadSmallExceptionHandlers(ref reader, dataSize / 12);
                }
            }
            else
            {
                exceptionHandlers = ImmutableArray <ExceptionRegion> .Empty;
            }

            return(new MethodBodyBlock(
                       localsInitialized,
                       maxStack,
                       localSignatureHandle,
                       ilBlock,
                       exceptionHandlers,
                       reader.Offset - startOffset));
        }
コード例 #13
0
        private static ImmutableArray<ExceptionRegion> ReadSmallExceptionHandlers(ref BlobReader memReader, int count)
        {
            var result = new ExceptionRegion[count];
            for (int i = 0; i < result.Length; i++)
            {
                var kind = (ExceptionRegionKind)memReader.ReadUInt16();
                var tryOffset = memReader.ReadUInt16();
                var tryLength = memReader.ReadByte();
                var handlerOffset = memReader.ReadUInt16();
                var handlerLength = memReader.ReadByte();
                var classTokenOrFilterOffset = memReader.ReadInt32();
                result[i] = new ExceptionRegion(kind, tryOffset, tryLength, handlerOffset, handlerLength, classTokenOrFilterOffset);
            }

            return ImmutableArray.Create(result);
        }
コード例 #14
0
        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);
        }
コード例 #15
0
        private MetadataRecord HandleConstant(Cts.Ecma.EcmaModule module, Ecma.ConstantHandle constantHandle)
        {
            Ecma.MetadataReader reader   = module.MetadataReader;
            Ecma.Constant       constant = reader.GetConstant(constantHandle);

            Ecma.BlobReader blob = reader.GetBlobReader(constant.Value);

            switch (constant.TypeCode)
            {
            case ConstantTypeCode.Boolean:
                return(new ConstantBooleanValue {
                    Value = blob.ReadBoolean()
                });

            case ConstantTypeCode.Byte:
                return(new ConstantByteValue {
                    Value = blob.ReadByte()
                });

            case ConstantTypeCode.Char:
                return(new ConstantCharValue {
                    Value = blob.ReadChar()
                });

            case ConstantTypeCode.Double:
                return(new ConstantDoubleValue {
                    Value = blob.ReadDouble()
                });

            case ConstantTypeCode.Int16:
                return(new ConstantInt16Value {
                    Value = blob.ReadInt16()
                });

            case ConstantTypeCode.Int32:
                return(new ConstantInt32Value {
                    Value = blob.ReadInt32()
                });

            case ConstantTypeCode.Int64:
                return(new ConstantInt64Value {
                    Value = blob.ReadInt64()
                });

            case ConstantTypeCode.SByte:
                return(new ConstantSByteValue {
                    Value = blob.ReadSByte()
                });

            case ConstantTypeCode.Single:
                return(new ConstantSingleValue {
                    Value = blob.ReadSingle()
                });

            case ConstantTypeCode.String:
                return(HandleString(blob.ReadUTF16(blob.Length)));

            case ConstantTypeCode.UInt16:
                return(new ConstantUInt16Value {
                    Value = blob.ReadUInt16()
                });

            case ConstantTypeCode.UInt32:
                return(new ConstantUInt32Value {
                    Value = blob.ReadUInt32()
                });

            case ConstantTypeCode.UInt64:
                return(new ConstantUInt64Value {
                    Value = blob.ReadUInt64()
                });

            case ConstantTypeCode.NullReference:
                return(new ConstantReferenceValue());

            default:
                throw new BadImageFormatException();
            }
        }
コード例 #16
0
        /// <summary>
        /// We want to know if a given method implements a redirected interface.
        /// For example, if we are given the method RemoveAt on a class "A" 
        /// which implements the IVector interface (which is redirected
        /// to IList in .NET) then this method would return true. The most 
        /// likely reason why we would want to know this is that we wish to hide
        /// (mark private) all methods which implement methods on a redirected 
        /// interface.
        /// </summary>
        /// <param name="memberRef">The declaration token for the method</param>
        /// <param name="isIDisposable">
        /// Returns true if the redirected interface is <see cref="IDisposable"/>.
        /// </param>
        /// <returns>True if the method implements a method on a redirected interface.
        /// False otherwise.</returns>
        private bool ImplementsRedirectedInterface(MemberReferenceHandle memberRef, out bool isIDisposable)
        {
            isIDisposable = false;

            EntityHandle parent = MemberRefTable.GetClass(memberRef);

            TypeReferenceHandle typeRef;
            if (parent.Kind == HandleKind.TypeReference)
            {
                typeRef = (TypeReferenceHandle)parent;
            }
            else if (parent.Kind == HandleKind.TypeSpecification)
            {
                BlobHandle blob = TypeSpecTable.GetSignature((TypeSpecificationHandle)parent);
                BlobReader sig = new BlobReader(BlobHeap.GetMemoryBlock(blob));

                if (sig.Length < 2 ||
                    sig.ReadByte() != (byte)CorElementType.ELEMENT_TYPE_GENERICINST ||
                    sig.ReadByte() != (byte)CorElementType.ELEMENT_TYPE_CLASS)
                {
                    return false;
                }

                EntityHandle token = sig.ReadTypeHandle();
                if (token.Kind != HandleKind.TypeReference)
                {
                    return false;
                }

                typeRef = (TypeReferenceHandle)token;
            }
            else
            {
                return false;
            }

            return GetProjectionIndexForTypeReference(typeRef, out isIDisposable) >= 0;
        }
コード例 #17
0
ファイル: PdbToXml.cs プロジェクト: GloryChou/roslyn
        private unsafe void WriteEditAndContinueLocalSlotMap(CustomDebugInfoRecord record)
        {
            Debug.Assert(record.Kind == CustomDebugInfoKind.EditAndContinueLocalSlotMap);

            _writer.WriteStartElement("encLocalSlotMap");
            try
            {
                int syntaxOffsetBaseline = -1;

                fixed (byte* compressedSlotMapPtr = &record.Data.ToArray()[0])
                {
                    var blobReader = new BlobReader(compressedSlotMapPtr, record.Data.Length);

                    while (blobReader.RemainingBytes > 0)
                    {
                        byte b = blobReader.ReadByte();

                        if (b == 0xff)
                        {
                            if (!blobReader.TryReadCompressedInteger(out syntaxOffsetBaseline))
                            {
                                _writer.WriteElementString("baseline", "?");
                                return;
                            }

                            syntaxOffsetBaseline = -syntaxOffsetBaseline;
                            continue;
                        }

                        _writer.WriteStartElement("slot");

                        if (b == 0)
                        {
                            // short-lived temp, no info
                            _writer.WriteAttributeString("kind", "temp");
                        }
                        else
                        {
                            int synthesizedKind = (b & 0x3f) - 1;
                            bool hasOrdinal = (b & (1 << 7)) != 0;

                            int syntaxOffset;
                            bool badSyntaxOffset = !blobReader.TryReadCompressedInteger(out syntaxOffset);
                            syntaxOffset += syntaxOffsetBaseline;

                            int ordinal = 0;
                            bool badOrdinal = hasOrdinal && !blobReader.TryReadCompressedInteger(out ordinal);

                            _writer.WriteAttributeString("kind", CultureInvariantToString(synthesizedKind));
                            _writer.WriteAttributeString("offset", badSyntaxOffset ? "?" : CultureInvariantToString(syntaxOffset));

                            if (badOrdinal || hasOrdinal)
                            {
                                _writer.WriteAttributeString("ordinal", badOrdinal ? "?" : CultureInvariantToString(ordinal));
                            }
                        }

                        _writer.WriteEndElement();
                    }
                }
            }
            finally
            {
                _writer.WriteEndElement(); //encLocalSlotMap
            }
        }
コード例 #18
0
            /// <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);
            }
コード例 #19
0
        private object ReadAndTranslateValue(ref BlobReader sigReader, SignatureTypeCode typeCode, out bool isEnumTypeCode)
        {
            switch (typeCode)
            {
                case SignatureTypeCode.Boolean:
                    isEnumTypeCode = true;
                    return (short)(sigReader.ReadBoolean() ? 1 : 0);

                case SignatureTypeCode.Char:
                    isEnumTypeCode = true;
                    return (ushort)sigReader.ReadChar();

                case SignatureTypeCode.SByte:
                    isEnumTypeCode = true;
                    return (short)sigReader.ReadSByte();

                case SignatureTypeCode.Byte:
                    isEnumTypeCode = true;
                    return (short)sigReader.ReadByte();

                case SignatureTypeCode.Int16:
                    isEnumTypeCode = true;
                    return sigReader.ReadInt16();

                case SignatureTypeCode.UInt16:
                    isEnumTypeCode = true;
                    return sigReader.ReadUInt16();

                case SignatureTypeCode.Int32:
                    isEnumTypeCode = true;
                    return sigReader.ReadInt32();

                case SignatureTypeCode.UInt32:
                    isEnumTypeCode = true;
                    return sigReader.ReadUInt32();

                case SignatureTypeCode.Int64:
                    isEnumTypeCode = true;
                    return sigReader.ReadInt64();

                case SignatureTypeCode.UInt64:
                    isEnumTypeCode = true;
                    return sigReader.ReadUInt64();

                case SignatureTypeCode.Single:
                    isEnumTypeCode = false;
                    return sigReader.ReadSingle();

                case SignatureTypeCode.Double:
                    isEnumTypeCode = false;
                    return sigReader.ReadDouble();

                case SignatureTypeCode.String:
                    isEnumTypeCode = false;

                    if (sigReader.RemainingBytes == 1)
                    {
                        if (sigReader.ReadByte() != 0xff)
                        {
                            throw new BadImageFormatException();
                        }

                        return NullReferenceValue;
                    }

                    if (sigReader.RemainingBytes % 2 != 0)
                    {
                        throw new BadImageFormatException();
                    }

                    return sigReader.ReadUTF16(sigReader.RemainingBytes);

                case SignatureTypeCode.Object:
                    // null reference
                    isEnumTypeCode = false;
                    return NullReferenceValue;

                default:
                    throw new BadImageFormatException();
            }
        }