Пример #1
0
        private IAttribute ReadBinarySecurityAttribute(ref SRM.BlobReader reader, CustomAttributeTypedArgument <IType> securityAction)
        {
            string attributeTypeName = reader.ReadSerializedString();
            IType  attributeType     = module.TypeProvider.GetTypeFromSerializedName(attributeTypeName);

            reader.ReadCompressedInteger();             // ??
            // The specification seems to be incorrect here, so I'm using the logic from Cecil instead.
            int numNamed = reader.ReadCompressedInteger();

            var decoder   = new Metadata.CustomAttributeDecoder <IType>(module.TypeProvider, module.metadata);
            var namedArgs = decoder.DecodeNamedArguments(ref reader, numNamed);

            return(new DefaultAttribute(
                       attributeType,
                       fixedArguments: ImmutableArray.Create(securityAction),
                       namedArguments: namedArgs));
        }
        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();
        }
Пример #3
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());
        }
        /// <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();
        }
        private unsafe static void UncompressLambdaMap(
            ImmutableArray<byte> compressedLambdaMap,
            out int methodOrdinal,
            out ImmutableArray<ClosureDebugInfo> closures,
            out ImmutableArray<LambdaDebugInfo> lambdas)
        {
            methodOrdinal = DebugId.UndefinedOrdinal;
            closures = default(ImmutableArray<ClosureDebugInfo>);
            lambdas = default(ImmutableArray<LambdaDebugInfo>);

            if (compressedLambdaMap.IsDefaultOrEmpty)
            {
                return;
            }

            var closuresBuilder = ArrayBuilder<ClosureDebugInfo>.GetInstance();
            var lambdasBuilder = ArrayBuilder<LambdaDebugInfo>.GetInstance();

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

                    // [-1, inf)
                    methodOrdinal = blobReader.ReadCompressedInteger() - 1;

                    int syntaxOffsetBaseline = -blobReader.ReadCompressedInteger();

                    int closureCount = blobReader.ReadCompressedInteger();

                    for (int i = 0; i < closureCount; i++)
                    {
                        int syntaxOffset = blobReader.ReadCompressedInteger();

                        var closureId = new DebugId(closuresBuilder.Count, generation: 0);
                        closuresBuilder.Add(new ClosureDebugInfo(syntaxOffset + syntaxOffsetBaseline, closureId));
                    }

                    while (blobReader.RemainingBytes > 0)
                    {
                        int syntaxOffset = blobReader.ReadCompressedInteger();
                        int closureOrdinal = blobReader.ReadCompressedInteger() + LambdaDebugInfo.MinClosureOrdinal;

                        if (closureOrdinal >= closureCount)
                        {
                            throw CreateInvalidDataException(compressedLambdaMap, blobReader.Offset);
                        }

                        var lambdaId = new DebugId(lambdasBuilder.Count, generation: 0);
                        lambdasBuilder.Add(new LambdaDebugInfo(syntaxOffset + syntaxOffsetBaseline, lambdaId, closureOrdinal));
                    }
                }
                catch (BadImageFormatException)
                {
                    throw CreateInvalidDataException(compressedLambdaMap, blobReader.Offset);
                }
            }

            closures = closuresBuilder.ToImmutableAndFree();
            lambdas = lambdasBuilder.ToImmutableAndFree();
        }
Пример #6
0
        private int ReadDocumentRowId(ref BlobReader reader)
        {
            int rowId = reader.ReadCompressedInteger();
            if (rowId == 0)
            {
                throw new BadImageFormatException("Invalid handle");
            }

            return rowId;
        }
Пример #7
0
        private ushort ReadColumn(ref BlobReader reader)
        {
            int column = reader.ReadCompressedInteger();
            if (column > ushort.MaxValue)
            {
                throw new BadImageFormatException("SequencePointValueOutOfRange");
            }

            return (ushort)column;
        }
Пример #8
0
 private int ReadLine(ref BlobReader reader)
 {
     return reader.ReadCompressedInteger();
 }
Пример #9
0
 private void ReadDeltaLinesAndColumns(ref BlobReader reader, out int deltaLines, out int deltaColumns)
 {
     deltaLines = reader.ReadCompressedInteger();
     deltaColumns = (deltaLines == 0) ? reader.ReadCompressedInteger() : reader.ReadCompressedSignedInteger();
 }
Пример #10
0
 private BlobReader GetBlobReader(BlobHandle handle)
 {
     int offset = MetadataTokens.GetHeapOffset(handle);
     byte* start = _blobHeapBlob.Pointer + offset;
     var reader = new BlobReader(start, _blobHeapBlob.Length - offset);
     int size = reader.ReadCompressedInteger();
     return new BlobReader(start + reader.Offset, size);
 }
Пример #11
0
 private TypeSignature DecodeGenericTypeParameter(
     ref BlobReader signatureReader,
     ImmutableArray<string> typeParameters,
     int containingArity)
 {
     int index = signatureReader.ReadCompressedInteger();
     if (index < containingArity)
     {
         // Unspecified type parameter.
         throw UnhandledMetadata();
     }
     var name = typeParameters[index - containingArity];
     return new QualifiedTypeSignature(null, name);
 }
Пример #12
0
        public unsafe int GetSignature(
            int bufferLength,
            out int count,
            [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0), Out]byte[] signature)
        {
            var localSignatureHandle = _symMethod.MetadataReader.GetMethodBody(_symMethod.BodyHandle).LocalSignature;
            var metadataImport = _symMethod.SymReader.PdbReader.MetadataImport;
            var local = _symMethod.MetadataReader.GetLocalVariable(_handle);

            byte* signaturePtr;
            int signatureLength;
            int hr = metadataImport.GetSigFromToken(MetadataTokens.GetToken(localSignatureHandle), out signaturePtr, out signatureLength);
            if (hr != HResult.S_OK)
            {
                count = 0;
                return hr;
            }

            var signatureReader = new BlobReader(signaturePtr, signatureLength);

           SignatureHeader header = signatureReader.ReadSignatureHeader();
            if (header.Kind != SignatureKind.LocalVariables)
            {
                count = 0;
                return HResult.E_FAIL;
            }

            int slotCount = signatureReader.ReadCompressedInteger();
            int slotIndex = local.Index;
            if (slotIndex >= slotCount)
            {
                count = 0;
                return HResult.E_FAIL;
            }

            var typeProvider = new DummyTypeProvider(_symMethod.MetadataReader);

            for (int i = 0; i < slotIndex - 1; i++)
            {
                SignatureDecoder.DecodeType(ref signatureReader, typeProvider);
            }

            int localSlotStart = signatureReader.Offset;
            SignatureDecoder.DecodeType(ref signatureReader, typeProvider);
            int localSlotLength = signatureReader.Offset - localSlotStart;

            if (localSlotLength <= bufferLength)
            {
                Marshal.Copy((IntPtr)(signaturePtr + localSlotStart), signature, 0, localSlotLength);
            }

            count = localSlotLength;
            return HResult.S_OK;
        }
            public bool MoveNext()
            {
                if (_reader.RemainingBytes == 0)
                {
                    return(false);
                }

                DocumentHandle document = _current.Document;
                int            offset, deltaLines, deltaColumns, startLine;
                ushort         startColumn;

                if (_reader.Offset == 0)
                {
                    // header (skip local signature rid):
                    _reader.ReadCompressedInteger();

                    if (document.IsNil)
                    {
                        document = ReadDocumentHandle();
                    }
                    // IL offset:
                    offset = _reader.ReadCompressedInteger();
                }
                else
                {
                    // skip all document records and update the current document accordingly:
                    int deltaOffset;
                    while ((deltaOffset = _reader.ReadCompressedInteger()) == 0)
                    {
                        document = ReadDocumentHandle();
                    }

                    // IL offset:
                    offset = AddOffsets(_current.Offset, deltaOffset);
                }

                ReadDeltaLinesAndColumns(out deltaLines, out deltaColumns);

                // hidden
                if (deltaLines == 0 && deltaColumns == 0)
                {
                    _current = new SequencePoint(document, offset);
                    return(true);
                }

                // delta Start Line & Column:
                if (_previousNonHiddenStartLine < 0)
                {
                    Debug.Assert(_previousNonHiddenStartColumn == 0);

                    startLine   = ReadLine();
                    startColumn = ReadColumn();
                }
                else
                {
                    startLine   = AddLines(_previousNonHiddenStartLine, _reader.ReadCompressedSignedInteger());
                    startColumn = AddColumns(_previousNonHiddenStartColumn, _reader.ReadCompressedSignedInteger());
                }

                _previousNonHiddenStartLine   = startLine;
                _previousNonHiddenStartColumn = startColumn;

                _current = new SequencePoint(
                    document,
                    offset,
                    startLine,
                    startColumn,
                    AddLines(startLine, deltaLines),
                    AddColumns(startColumn, deltaColumns));

                return(true);
            }