Example #1
0
        /// <summary>
        /// Reads a raw method body from the given binary input stream using the fat method body format.
        /// </summary>
        /// <param name="errorListener">The object responsible for recording parser errors.</param>
        /// <param name="reader">The binary input stream to read from.</param>
        /// <returns>The raw method body.</returns>
        /// <exception cref="FormatException">Occurs when the method header indicates an method body that is not in the
        /// fat format.</exception>
        public new static CilRawFatMethodBody FromReader(IErrorListener errorListener, IBinaryStreamReader reader)
        {
            ulong fileOffset = reader.Offset;
            uint  rva        = reader.Rva;

            // Read flags.
            ushort header     = reader.ReadUInt16();
            var    flags      = (CilMethodBodyAttributes)(header & 0xFFF);
            int    headerSize = (header >> 12) * sizeof(uint);

            // Verify this is a fat method body.
            if ((flags & CilMethodBodyAttributes.Fat) != CilMethodBodyAttributes.Fat)
            {
                errorListener.BadImage("Invalid fat CIL method body header.");
                return(null);
            }

            // Read remaining header.
            ushort maxStack         = reader.ReadUInt16();
            uint   codeSize         = reader.ReadUInt32();
            uint   localVarSigToken = reader.ReadUInt32();

            // Move to code.
            reader.Offset = fileOffset + (ulong)headerSize;

            // Verify code size.
            if (reader.Offset + codeSize > reader.StartOffset + reader.Length)
            {
                errorListener.BadImage("Invalid fat CIL method body code size.");
                return(null);
            }

            // Read code.
            var code = new byte[codeSize];

            reader.ReadBytes(code, 0, code.Length);

            // Create body.
            var body = new CilRawFatMethodBody(flags, maxStack, localVarSigToken, code);

            body.UpdateOffsets(fileOffset, rva);

            // Read any extra sections.
            if (body.HasSections)
            {
                reader.Align(4);

                CilExtraSection section;
                do
                {
                    section = CilExtraSection.FromReader(reader);
                    body.ExtraSections.Add(section);
                } while (section.HasMoreSections);
            }

            return(body);
        }
Example #2
0
        /// <summary>
        /// Reads a raw method body from the given binary input stream.
        /// </summary>
        /// <param name="errorListener">The object responsible for recording parser errors.</param>
        /// <param name="reader">The binary input stream to read from.</param>
        /// <returns>The raw method body.</returns>
        /// <exception cref="NotSupportedException">Occurs when the method header indicates an invalid or unsupported
        /// method body format.</exception>
        public static CilRawMethodBody FromReader(IErrorListener errorListener, IBinaryStreamReader reader)
        {
            var flag = (CilMethodBodyAttributes)reader.ReadByte();

            reader.Offset--;

            if ((flag & CilMethodBodyAttributes.Fat) == CilMethodBodyAttributes.Fat)
            {
                return(CilRawFatMethodBody.FromReader(errorListener, reader));
            }
            if ((flag & CilMethodBodyAttributes.Tiny) == CilMethodBodyAttributes.Tiny)
            {
                return(CilRawTinyMethodBody.FromReader(errorListener, reader));
            }

            throw new NotSupportedException("Invalid or unsupported method body format.");
        }