/// <summary>
 /// 
 /// </summary>
 /// <param name="clause"></param>
 private void AddClauseLabels(EhClause clause)
 {
     AddClauseLabel(clause, clause.TryOffset);
     AddClauseLabel(clause, clause.TryEnd);
     AddClauseLabel(clause, clause.HandlerOffset);
     AddClauseLabel(clause, clause.HandlerEnd);
 }
Exemple #2
0
        /// <summary>
        /// Reads the method header from the instruction stream.
        /// </summary>
        /// <param name="reader">The reader used to decode the instruction stream.</param>
        /// <param name="header">The method header structure to populate.</param>
        private void ReadMethodHeader(BinaryReader reader, ref MethodHeader header)
        {
            // Read first byte
            header.flags = (MethodFlags)reader.ReadByte();

            // Check least significant 2 bits
            switch (header.flags & MethodFlags.HeaderMask)
            {
            case MethodFlags.TinyFormat:
                header.codeSize = ((uint)(header.flags & MethodFlags.TinyCodeSizeMask) >> 2);
                header.flags   &= MethodFlags.HeaderMask;
                break;

            case MethodFlags.FatFormat:
                // Read second byte of flags
                header.flags = (MethodFlags)(reader.ReadByte() << 8 | (byte)header.flags);
                if (MethodFlags.ValidHeader != (header.flags & MethodFlags.HeaderSizeMask))
                {
                    throw new InvalidDataException(@"Invalid method _header.");
                }
                header.maxStack        = reader.ReadUInt16();
                header.codeSize        = reader.ReadUInt32();
                header.localsSignature = new Token(reader.ReadUInt32());                         // ReadStandAloneSigRow
                break;

            default:
                throw new InvalidDataException(@"Invalid method header while trying to decode " + this.methodCompiler.Method.ToString() + ". (Flags = " + header.flags.ToString("X") + ", Rva = " + this.methodCompiler.Method.Rva + ")");
            }

            // Are there sections following the code?
            if (MethodFlags.MoreSections == (header.flags & MethodFlags.MoreSections))
            {
                // Yes, seek to them and process those sections
                long codepos = reader.BaseStream.Position;

                // Seek to the end of the code...
                long dataSectPos = codepos + header.codeSize;
                if (0 != (dataSectPos & 3))
                {
                    dataSectPos += (4 - (dataSectPos % 4));
                }
                reader.BaseStream.Position = dataSectPos;

                // Read all headers, so the IL decoder knows how to handle these...
                byte flags;

                do
                {
                    flags = reader.ReadByte();
                    bool isFat = (0x40 == (flags & 0x40));
                    int  length;
                    int  blocks;
                    if (isFat)
                    {
                        byte[] buffer = new byte[4];
                        reader.Read(buffer, 0, 3);
                        length = LittleEndianBitConverter.GetInt32(buffer, 0);
                        blocks = (length - 4) / 24;
                    }
                    else
                    {
                        length = reader.ReadByte();
                        blocks = (length - 4) / 12;

                        /* Read & skip the padding. */
                        reader.ReadInt16();
                    }

                    Debug.Assert(0x01 == (flags & 0x3F), @"Unsupported method data section.");
                    // Read the clause
                    for (int i = 0; i < blocks; i++)
                    {
                        EhClause clause = new EhClause();
                        clause.Read(reader, isFat);
                        //this.methodCompiler.Method.ExceptionClauseHeader.AddClause(clause);
                        // FIXME: Create proper basic Blocks for each item in the clause
                    }
                }while (0x80 == (flags & 0x80));

                //methodCompiler.Method.ExceptionClauseHeader.Sort();
                reader.BaseStream.Position = codepos;
            }
        }
        /// <summary>
        /// Reads the method header from the instruction stream.
        /// </summary>
        /// <param name="reader">The reader used to decode the instruction stream.</param>
        /// <param name="header">The method header structure to populate.</param>
        private void ReadMethodHeader(BinaryReader reader, ref MethodHeader header)
        {
            header.flags = (MethodFlags)reader.ReadByte();
            switch (header.flags & MethodFlags.HeaderMask)
            {
                case MethodFlags.TinyFormat:
                    header.codeSize = ((uint)(header.flags & MethodFlags.TinyCodeSizeMask) >> 2);
                    header.flags &= MethodFlags.HeaderMask;
                    break;

                case MethodFlags.FatFormat:
                    header.flags = (MethodFlags)(reader.ReadByte() << 8 | (byte)header.flags);
                    if (MethodFlags.ValidHeader != (header.flags & MethodFlags.HeaderSizeMask))
                        throw new InvalidDataException(@"Invalid method _header.");
                    header.maxStack = reader.ReadUInt16();
                    header.codeSize = reader.ReadUInt32();
                    header.localsSignature = (TokenTypes)reader.ReadUInt32();
                    break;

                default:
                    throw new InvalidDataException(@"Invalid method header.");
            }

            // Are there sections following the code?
            if (MethodFlags.MoreSections == (header.flags & MethodFlags.MoreSections))
            {
                // Yes, seek to them and process those sections
                long codepos = reader.BaseStream.Position;

                // Seek to the end of the code...
                long dataSectPos = codepos + header.codeSize;
                if (0 != (dataSectPos & 3))
                    dataSectPos += (4 - (dataSectPos % 4));
                reader.BaseStream.Position = dataSectPos;

                // Read all headers, so the IL decoder knows how to handle these...
                byte flags;

                do
                {
                    flags = reader.ReadByte();
                    bool isFat = (0x40 == (flags & 0x40));
                    int length;
                    int blocks;
                    if (isFat)
                    {
                        byte[] buffer = new byte[4];
                        reader.Read(buffer, 0, 3);
                        length = LittleEndianBitConverter.GetInt32(buffer, 0);
                        blocks = (length - 4) / 24;
                    }
                    else
                    {
                        length = reader.ReadByte();
                        blocks = (length - 4) / 12;

                        /* Read & skip the padding. */
                        reader.ReadInt16();
                    }

                    Debug.Assert(0x01 == (flags & 0x3F), @"Unsupported method data section.");
                    // Read the clause
                    for (int i = 0; i < blocks; i++)
                    {
                        EhClause clause = new EhClause();
                        clause.Read(reader, isFat);
                        this.methodCompiler.Method.ExceptionClauseHeader.AddClause(clause);
                        // FIXME: Create proper basic Blocks for each item in the clause
                    }
                }
                while (0x80 == (flags & 0x80));

                methodCompiler.Method.ExceptionClauseHeader.Sort();
                reader.BaseStream.Position = codepos;
            }
        }
Exemple #4
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="clause"></param>
 public void AddClause(EhClause clause)
 {
     this.Clauses.Add(clause);
 }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="clause"></param>
 /// <param name="label"></param>
 private void AddClauseLabel(EhClause clause, int label)
 {
     this.labelMapping[label] = clause;
 }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="clause"></param>
 public void AddClause(EhClause clause)
 {
     this.Clauses.Add(clause);
 }