예제 #1
0
        public static int ReadCompressedInteger(this IBinaryAccessor accessor)
        {
            int  result = 0;
            byte b      = accessor.ReadByte();

            if ((b & 0x80) == 0)
            {
                // 1 byte
                result = b;
            }
            else if ((b & 0x40) == 0)
            {
                // 2 byte
                result  = (b & ~0x80) << 8;
                result |= accessor.ReadByte();
            }
            else
            {
                // 4 byte
                result  = (b & ~0xc0) << 24;
                result |= accessor.ReadByte() << 16;
                result |= accessor.ReadByte() << 8;
                result |= accessor.ReadByte();
            }

            return(result);
        }
        internal void Read(IBinaryAccessor accessor)
        {
            // Reserved, 4 bytes
            accessor.ReadInt32();

            _schemaMajorVersion = accessor.ReadByte();
            _schemaMinorVersion = accessor.ReadByte();

            byte heapFlags = accessor.ReadByte();

            // Reserved, 1 bytes
            accessor.ReadByte();

            ulong validMask = accessor.ReadUInt64();

            _sortMask = accessor.ReadUInt64();

            // Row counts
            int[] rowCounts = new int[MetadataConstants.TableCount];
            for (int tableType = 0; tableType < MetadataConstants.TableCount; tableType++)
            {
                if ((validMask & (1UL << tableType)) != 0)
                {
                    rowCounts[tableType] = accessor.ReadInt32();
                }
            }

            var compressionInfo = TableCompressionInfo.Create(_metadata, rowCounts, heapFlags);

            // Tables
            for (int tableType = 0; tableType < MetadataConstants.TableCount; tableType++)
            {
                _tables[tableType].Read(accessor, compressionInfo, rowCounts[tableType]);
            }
        }
        private static CustomAttributeTypedArgument LoadObject(IBinaryAccessor accessor, Module module)
        {
            bool isArray     = false;
            int  elementType = (int)accessor.ReadByte();

            if (elementType == ElementType.SzArray)
            {
                isArray     = true;
                elementType = (int)accessor.ReadByte();
            }

            switch (elementType)
            {
            case ElementType.Enum:
            {
                string enumTypeName = CustomAttributeHelper.ReadBlobString(accessor);
                int    length       = isArray ? CustomAttributeHelper.ReadArrayLength(accessor) : 1;
                return(LoadEnum(accessor, module, enumTypeName, isArray, length));
            }

            default:
            {
                int length = isArray ? CustomAttributeHelper.ReadArrayLength(accessor) : 1;
                return(Load(accessor, module, elementType, isArray, length));
            }
            }
        }
        private ExceptionHandler LoadTinyExceptionHandler(IBinaryAccessor accessor, Module module)
        {
            var handler = new ExceptionHandler();

            int flags = accessor.ReadInt16() & ILExceptionFlag.MASK;

            switch (flags)
            {
            case 0:
                handler.Type = ExceptionHandlerType.Catch;
                break;

            case 1:
                handler.Type = ExceptionHandlerType.Filter;
                break;

            case 2:
                handler.Type = ExceptionHandlerType.Finally;
                break;

            case 4:
                handler.Type = ExceptionHandlerType.Fault;
                break;
            }

            handler.TryOffset     = accessor.ReadUInt16();
            handler.TryLength     = accessor.ReadByte();
            handler.HandlerOffset = accessor.ReadUInt16();
            handler.HandlerLength = accessor.ReadByte();

            switch (handler.Type)
            {
            case ExceptionHandlerType.Catch:
            {
                int token = accessor.ReadInt32();
                handler.CatchType = TypeSignature.Load(module, token);
            }
            break;

            case ExceptionHandlerType.Filter:
            {
                handler.FilterOffset = accessor.ReadInt32();
            }
            break;

            default:
            {
                accessor.Position += 4;                                 // padded
            }
            break;
            }

            return(handler);
        }
        internal static CustomAttributeNamedArgument Load(IBinaryAccessor accessor, Module module)
        {
            var argument = new CustomAttributeNamedArgument();

            int argumentType = accessor.ReadByte();

            switch (argumentType)
            {
            case Metadata.ElementType.Field:
                argument._type = CustomAttributeNamedArgumentType.Field;
                break;

            case Metadata.ElementType.Property:
                argument._type = CustomAttributeNamedArgumentType.Property;
                break;

            default:
                throw new InvalidDataException();
            }

            bool isArray     = false;
            int  elementType = accessor.ReadByte();

            if (elementType == ElementType.SzArray)
            {
                elementType = accessor.ReadByte();
                isArray     = true;
            }

            switch (elementType)
            {
            case ElementType.Enum:
            {
                string enumTypeName = CustomAttributeHelper.ReadBlobString(accessor);
                enumTypeName   = enumTypeName.TrimEnd(new char[] { '\0' });
                argument._name = CustomAttributeHelper.ReadBlobString(accessor);
                int arrayLength = isArray ? CustomAttributeHelper.ReadArrayLength(accessor) : 1;
                argument._value = CustomAttributeTypedArgument.LoadEnum(accessor, module, enumTypeName, isArray, arrayLength);
            }
            break;

            default:
            {
                argument._name = CustomAttributeHelper.ReadBlobString(accessor);
                int arrayLength = isArray ? CustomAttributeHelper.ReadArrayLength(accessor) : 1;
                argument._value = CustomAttributeTypedArgument.Load(accessor, module, elementType, isArray, arrayLength);
            }
            break;
            }

            return(argument);
        }
        private void LoadExceptionHandlerSection(IBinaryAccessor accessor, Module module, int flags)
        {
            if (_exceptionHandlers == null)
            {
                _exceptionHandlers = new List <ExceptionHandler>();
            }

            if ((flags & 0x40) == 0x40)
            {
                // Fat format
                accessor.Position--;
                int length = (accessor.ReadInt32() >> 8) / 24;
                for (int i = 0; i < length; i++)
                {
                    var handler = LoadFatExceptionHandler(accessor, module);
                    _exceptionHandlers.Add(handler);
                }
            }
            else
            {
                // Tiny format
                int length = accessor.ReadByte() / 12;
                accessor.Position += 2;                 // padded
                for (int i = 0; i < length; i++)
                {
                    var handler = LoadTinyExceptionHandler(accessor, module);
                    _exceptionHandlers.Add(handler);
                }
            }
        }
        private static MarshalType Load(IBinaryAccessor accessor, CodeNode parent)
        {
            var unmanagedType = (UnmanagedType)accessor.ReadByte();
            var marshalType   = CreateNew(parent, unmanagedType);

            marshalType.Load(accessor);

            return(marshalType);
        }
        private static CustomAttributeTypedArgument LoadBool(IBinaryAccessor accessor, Module module, bool isArray, int arrayLength)
        {
            var type = TypeReference.GetPrimitiveType(PrimitiveTypeCode.Boolean, module.Assembly);

            if (isArray)
            {
                var value = new bool[arrayLength];
                for (int i = 0; i < arrayLength; i++)
                {
                    value[i] = accessor.ReadByte() != 0;
                }

                return(new CustomAttributeTypedArgument(value, type));
            }
            else
            {
                bool value = accessor.ReadByte() != 0;
                return(new CustomAttributeTypedArgument(value, type));
            }
        }
        protected internal override void Read(IBinaryAccessor accessor, TableCompressionInfo compressionInfo, int count)
        {
            if (count == 0)
            {
                return;
            }

            var rows = new ConstantRow[count];

            for (int i = 0; i < count; i++)
            {
                var row = new ConstantRow();
                row.Type = (ConstantTableType)accessor.ReadByte();
                accessor.ReadByte();                 // Padding
                row.Parent = accessor.ReadCell(compressionInfo.CodedTokenDataSize4[1]);
                row.Value  = accessor.ReadCell(compressionInfo.BlobHeapOffsetSize4);

                rows[i] = row;
            }

            _count = count;
            _rows  = rows;
        }
        internal static string ReadBlobString(IBinaryAccessor accessor)
        {
            int  len = 0;
            byte b   = accessor.ReadByte();

            if (b == 0)
            {
                return(string.Empty);
            }

            if (b == 0xff)
            {
                return(null);
            }

            if ((b & 0x80) == 0)
            {
                // 1 byte
                len = b;
            }
            else if ((b & 0x40) == 0)
            {
                // 2 byte
                len  = (b & ~0x80) << 8;
                len |= accessor.ReadByte();
            }
            else
            {
                // 4 byte
                len  = (b & ~0xc0) << 24;
                len |= accessor.ReadByte() << 16;
                len |= accessor.ReadByte() << 8;
                len |= accessor.ReadByte();
            }

            return(accessor.ReadString(len, Encoding.UTF8));
        }
        private void Load(IBinaryAccessor accessor, Module module)
        {
            int flags = accessor.ReadByte();

            if ((flags & ILMethodFlags.FormatMask) == ILMethodFlags.FatFormat)
            {
                // Fat format
                accessor.ReadByte();
                _maxStackSize = accessor.ReadUInt16();
                int codeSize = accessor.ReadInt32();

                _initLocals    = ((flags & ILMethodFlags.InitLocals) == ILMethodFlags.InitLocals);
                _localVarToken = accessor.ReadInt32();

                if (MetadataToken.GetType(_localVarToken) == MetadataTokenType.Signature)
                {
                    LoadLocalVariables(module, MetadataToken.GetRID(_localVarToken));
                }

                LoadInstructions(accessor, module, codeSize);

                if ((flags & ILMethodFlags.MoreSects) == ILMethodFlags.MoreSects)
                {
                    // More sections
                    LoadSection(accessor, module);
                }
            }
            else
            {
                // Tiny format
                // Used when the method is tiny (< 64 bytes), and there are no local vars
                _maxStackSize = 8;
                int codeSize = flags >> 2;
                LoadInstructions(accessor, module, codeSize);
            }
        }
        /// <summary>
        /// Reads a Boolean value.
        /// </summary>
        /// <returns>true if the byte is nonzero; otherwise, false.</returns>
        public static bool?ReadNullableBoolean(this IBinaryAccessor accessor)
        {
            byte b = accessor.ReadByte();

            if (b == 0)
            {
                return(false);
            }
            else if (b == 1)
            {
                return(true);
            }
            else
            {
                return(null);
            }
        }
예제 #13
0
        protected void LoadSignature(IBinaryAccessor accessor, ModuleImage image)
        {
            byte sigType = accessor.ReadByte();

            if ((sigType & Metadata.SignatureType.Property) != Metadata.SignatureType.Property)
            {
                throw new CodeModelException(string.Format(SR.AssemblyLoadError, _module.Location));
            }

            _hasThis = ((sigType & Metadata.SignatureType.HasThis) == Metadata.SignatureType.HasThis);

            int paramCount = accessor.ReadCompressedInteger();

            _returnType = TypeSignature.Load(accessor, _module);

            _parameters = new PropertyParameterCollection(this);
            _parameters.Load(accessor, paramCount);
        }
        private void LoadSection(IBinaryAccessor accessor, Module module)
        {
            accessor.Align(4);

            int flags = accessor.ReadByte();

            if ((flags & ILMethodSect.EHTable) == ILMethodSect.EHTable)
            {
                // EHTable
                LoadExceptionHandlerSection(accessor, module, flags);
            }

            if ((flags & ILMethodSect.MoreSects) == ILMethodSect.MoreSects)
            {
                // More sections
                LoadSection(accessor, module);
            }
        }
        protected void LoadSignature(IBinaryAccessor accessor, ModuleImage image)
        {
            _sigType = accessor.ReadByte();

            if ((_sigType & Metadata.SignatureType.Generic) == Metadata.SignatureType.Generic)
            {
                accessor.ReadCompressedInteger();                 // GenericParameterCount (unused)
            }
            int paramCount = accessor.ReadCompressedInteger();

            int[] rids;
            image.GetParamsByMethod(_rid, out rids);

            int ridIndex = 0;

            _returnType = new MethodReturnType(this);
            _returnType.Load(accessor, rids, ref ridIndex);

            if (paramCount > 0)
            {
                _parameters = new MethodParameterCollection(this);
                _parameters.Load(accessor, paramCount, rids, ridIndex);
            }
        }
예제 #16
0
        protected internal override void Load(IBinaryAccessor accessor)
        {
            _arraySubType = (UnmanagedType)accessor.ReadByte();

            // The value MAX is used to indicate "no info."
            if (_arraySubType == UnmanagedType.Max)
            {
                return;
            }

            if (accessor.IsEof())
            {
                return;
            }

            if (_arraySubType == UnmanagedType.IUnknown ||
                _arraySubType == UnmanagedType.IDispatch ||
                _arraySubType == UnmanagedType.Interface)
            {
                _iidParameterIndex = accessor.ReadCompressedInteger();
            }

            if (accessor.IsEof())
            {
                return;
            }

            _lengthParamIndex = accessor.ReadCompressedInteger();

            if (accessor.IsEof())
            {
                return;
            }

            _arrayLength = accessor.ReadCompressedInteger();
        }
예제 #17
0
 internal void Read(IBinaryAccessor accessor, ProjectReadState state)
 {
     _duplicateBehavior = (MergeDuplicateBehavior)accessor.ReadByte();
 }
        private void StateLoadInstructions(IBinaryAccessor accessor, Module module)
        {
            int instructionCount = accessor.Read7BitEncodedInt();

            _instructions = new List <Instruction>(instructionCount);

            for (int i = 0; i < instructionCount; i++)
            {
                OpCode opCode;
                byte   opByte = accessor.ReadByte();
                if (opByte == 0xFE)
                {
                    opByte = accessor.ReadByte();
                    opCode = OpCodes.OpCodeArray[256 + opByte];
                }
                else
                {
                    opCode = OpCodes.OpCodeArray[opByte];
                }

                object value;
                switch (opCode.OperandType)
                {
                case OperandType.InlineBrTarget:
                {
                    value = accessor.ReadInt32();
                }
                break;

                case OperandType.InlineField:
                {
                    int token = accessor.ReadInt32();
                    value = module.GetSignature <Signature>(token);
                }
                break;

                case OperandType.InlineI:
                {
                    value = accessor.ReadInt32();
                }
                break;

                case OperandType.InlineI8:
                {
                    value = accessor.ReadInt64();
                }
                break;

                case OperandType.InlineMethod:
                {
                    int token = accessor.ReadInt32();
                    value = module.GetSignature <Signature>(token);
                }
                break;

                case OperandType.InlineR:
                {
                    value = accessor.ReadDouble();
                }
                break;

                case OperandType.InlineSig:
                {
                    int token = accessor.ReadInt32();
                    value = module.GetSignature <Signature>(token);
                }
                break;

                case OperandType.InlineString:
                {
                    // Token of a userdefined string, whose RID portion is actually an offset in the #US blob stream.
                    value = accessor.ReadLengthPrefixedString(Encoding.Unicode);
                }
                break;

                case OperandType.InlineSwitch:
                {
                    int   count   = accessor.ReadInt32();
                    int[] targets = new int[count];
                    for (int j = 0; j < count; j++)
                    {
                        targets[j] = accessor.ReadInt32();
                    }

                    value = targets;
                }
                break;

                case OperandType.InlineTok:
                {
                    int token = accessor.ReadInt32();
                    value = module.GetSignature <Signature>(token);
                }
                break;

                case OperandType.InlineType:
                {
                    int token = accessor.ReadInt32();
                    value = module.GetSignature <Signature>(token);
                }
                break;

                case OperandType.InlineVar:
                {
                    value = accessor.ReadInt16();
                }
                break;

                case OperandType.ShortInlineBrTarget:
                {
                    value = accessor.ReadSByte();
                }
                break;

                case OperandType.ShortInlineI:
                {
                    value = accessor.ReadByte();
                }
                break;

                case OperandType.ShortInlineR:
                {
                    value = accessor.ReadSingle();
                }
                break;

                case OperandType.ShortInlineVar:
                {
                    value = accessor.ReadByte();
                }
                break;

                default:
                {
                    value = null;
                }
                break;
                }

                _instructions.Add(new Instruction(opCode, value));
            }
        }
        private void LoadInstructions(IBinaryAccessor accessor, Module module, int codeSize)
        {
            long startOffset = accessor.Position;

            var image = module.Image;

            _instructions = new List <Instruction>();

            while (accessor.Position < startOffset + codeSize)
            {
                OpCode opCode;
                byte   opByte = accessor.ReadByte();
                if (opByte == 0xFE)
                {
                    opByte = accessor.ReadByte();
                    opCode = OpCodes.OpCodeArray[256 + opByte];
                }
                else
                {
                    opCode = OpCodes.OpCodeArray[opByte];
                }

                if (opCode == null)
                {
                    throw new CodeModelException(string.Format(SR.AssemblyLoadError, module.Location));
                }

                object value;
                switch (opCode.OperandType)
                {
                case OperandType.InlineBrTarget:
                {
                    value = accessor.ReadInt32();
                }
                break;

                case OperandType.InlineField:
                {
                    int token = accessor.ReadInt32();
                    value = FieldReference.Load(module, token);
                }
                break;

                case OperandType.InlineI:
                {
                    value = accessor.ReadInt32();
                }
                break;

                case OperandType.InlineI8:
                {
                    value = accessor.ReadInt64();
                }
                break;

                case OperandType.InlineMethod:
                {
                    int token = accessor.ReadInt32();
                    value = MethodReference.Load(module, token);
                }
                break;

                case OperandType.InlineR:
                {
                    value = accessor.ReadDouble();
                }
                break;

                case OperandType.InlineSig:
                {
                    int token = accessor.ReadInt32();
                    if (MetadataToken.GetType(token) == MetadataTokenType.Signature)
                    {
                        int rid = MetadataToken.GetRID(token);
                        value = CallSite.LoadStandAloneSig(module, rid);
                    }
                    else
                    {
                        throw new CodeModelException(SR.MethodBodyBlobNotValid);
                    }
                }
                break;

                case OperandType.InlineString:
                {
                    // Token of a userdefined string, whose RID portion is actually an offset in the #US blob stream.
                    uint token = accessor.ReadUInt32();
                    int  rid   = (int)(token & 0x00ffffff);
                    value = image.GetUserString(rid);
                }
                break;

                case OperandType.InlineSwitch:
                {
                    int   count   = accessor.ReadInt32();
                    int[] targets = new int[count];
                    for (int i = 0; i < count; i++)
                    {
                        targets[i] = accessor.ReadInt32();
                    }

                    value = targets;
                }
                break;

                case OperandType.InlineTok:
                {
                    int token = accessor.ReadInt32();
                    int rid   = MetadataToken.GetRID(token);
                    switch (MetadataToken.GetType(token))
                    {
                    case MetadataTokenType.Method:
                        value = MethodReference.LoadMethodDef(module, rid);
                        break;

                    case MetadataTokenType.MethodSpec:
                        value = GenericMethodReference.LoadMethodSpec(module, rid);
                        break;

                    case MetadataTokenType.MemberRef:
                        value = MethodReference.LoadMemberRef(module, rid);
                        break;

                    case MetadataTokenType.Field:
                        value = FieldReference.LoadFieldDef(module, rid);
                        break;

                    case MetadataTokenType.TypeDef:
                        value = TypeReference.LoadTypeDef(module, rid);
                        break;

                    case MetadataTokenType.TypeRef:
                        value = TypeReference.LoadTypeRef(module, rid);
                        break;

                    case MetadataTokenType.TypeSpec:
                        value = TypeSignature.LoadTypeSpec(module, rid);
                        break;

                    default:
                        throw new CodeModelException(SR.MethodBodyBlobNotValid);
                    }
                }
                break;

                case OperandType.InlineType:
                {
                    int token = accessor.ReadInt32();
                    value = TypeSignature.Load(module, token);
                }
                break;

                case OperandType.InlineVar:
                {
                    value = accessor.ReadInt16();
                }
                break;

                case OperandType.ShortInlineBrTarget:
                {
                    value = accessor.ReadSByte();
                }
                break;

                case OperandType.ShortInlineI:
                {
                    value = accessor.ReadByte();
                }
                break;

                case OperandType.ShortInlineR:
                {
                    value = accessor.ReadSingle();
                }
                break;

                case OperandType.ShortInlineVar:
                {
                    value = accessor.ReadByte();
                }
                break;

                default:
                {
                    value = null;
                }
                break;
                }

                _instructions.Add(new Instruction(opCode, value));
            }
        }
예제 #20
0
        internal static CallSite LoadCallSite(IBinaryAccessor accessor, Module module)
        {
            byte sigType = accessor.ReadByte();

            return(LoadCallSite(accessor, module, sigType));
        }