/// <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); }
/// <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."); }