Exemple #1
0
        private static TryCatchBlock CreateTryBlock(ILStream code, int tryOffset, int tryLength)
        {
            int entryIndex = code.GetOffsetIndex(tryOffset);
            int exitIndex  = GetIndex(code, tryOffset, tryLength);
            var tryBlock   = new TryCatchBlock
            {
                EntryPoint = code[entryIndex],
                ExitPoint  = code[exitIndex]
            };

            return(tryBlock);
        }
Exemple #2
0
        private static int GetIndex(ILStream code, int offset, int length)
        {
            int index = code.GetOffsetIndex(offset + length);

            if (index == code.Count - 1)
            {
                return(index);
            }

            index--;
            return(index >= 0 ? index : code.Count - 1);
        }
Exemple #3
0
        public void SetupInstructions(ILStream code)
        {
            Code = code;

            for (int i = EntryIndex; i <= ExitIndex; ++i)
            {
                var instr = code[i];
                if (instr.SehBlock == null)
                {
                    instr.SehBlock = this;
                    VisitInstruction(instr);
                }
            }
        }
Exemple #4
0
        private static void SetupInstructions(ILStream code, Block block)
        {
            foreach (var kid in block.Kids)
            {
                SetupInstructions(code, kid);
            }

            var tryBlock = block as TryCatchBlock;

            if (tryBlock != null)
            {
                foreach (var h in tryBlock.Handlers.Cast <HandlerBlock>())
                {
                    SetupInstructions(code, h);
                }
            }

            block.SetupInstructions(code);
        }
Exemple #5
0
        private ILStream ReadCode(IMethod method, IMethodContext context, BufferedBinaryReader reader, int codeSize)
        {
            var list     = new ILStream();
            var startPos = reader.Position;
            int offset   = 0;

            while (offset < codeSize)
            {
                var pos   = reader.Position;
                var instr = ReadInstruction(method, context, reader, startPos);
                var size  = reader.Position - pos;
                offset += (int)size;

                instr.Index = list.Count;
                list.Add(instr);

                if (!HasGenericInstructions && instr.IsGenericContext)
                {
                    _genericFlags |= GenericFlags.HasGenericInstructions;
                }
            }
            return(list);
        }
Exemple #6
0
 private static TryCatchBlock EnshureTryBlock(IList <SEHBlock> blocks, int i, TryCatchBlock tryBlock, ILStream code, SEHBlock block, ICollection <TryCatchBlock> list)
 {
     if (tryBlock == null)
     {
         tryBlock = CreateTryBlock(code, block.TryOffset, block.TryLength);
         list.Add(tryBlock);
     }
     else
     {
         var prev = blocks[i - 1];
         if (prev.TryOffset != block.TryOffset ||
             prev.TryLength != block.TryLength)
         {
             tryBlock = CreateTryBlock(code, block.TryOffset, block.TryLength);
             list.Add(tryBlock);
         }
     }
     return(tryBlock);
 }
Exemple #7
0
        private IReadOnlyList <TryCatchBlock> TranslateSehBlocks(IMethod method, IMethodContext context, IList <SEHBlock> blocks, ILStream code)
        {
            var           list     = new List <TryCatchBlock>();
            var           handlers = new BlockList();
            TryCatchBlock tryBlock = null;
            int           n        = blocks.Count;

            for (int i = 0; i < n; ++i)
            {
                var block = blocks[i];
                tryBlock = EnshureTryBlock(blocks, i, tryBlock, code, block, list);
                var handler    = CreateHandlerBlock(method, context, code, block);
                int entryIndex = code.GetOffsetIndex(block.HandlerOffset);
                int exitIndex  = GetIndex(code, block.HandlerOffset, block.HandlerLength);
                handler.EntryPoint = code[entryIndex];
                handler.ExitPoint  = code[exitIndex];
                tryBlock.Handlers.Add(handler);
                handlers.Add(handler);
            }

            //set parents
            for (int i = 0; i < list.Count; ++i)
            {
                var block  = list[i];
                var parent = FindParent(list, block);
                if (parent != null)
                {
                    parent.Add(block);
                    list.RemoveAt(i);
                    --i;
                }
            }

            foreach (var block in list)
            {
                SetupInstructions(code, block);
            }

            return(list.AsReadOnlyList());
        }
Exemple #8
0
        public MethodBody(IMethod method, IMethodContext context, BufferedBinaryReader reader)
        {
            if (method == null)
            {
                throw new ArgumentNullException("method");
            }
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            }

            _method = method;

            int lsb   = reader.ReadUInt8();
            var flags = (MethodBodyFlags)lsb;

            _maxStackSize = 8;

            var             format    = flags & MethodBodyFlags.FormatMask;
            List <SEHBlock> sehBlocks = null;

            switch (format)
            {
            case MethodBodyFlags.FatFormat:
            {
                byte msb = reader.ReadUInt8();
                int  dwordMultipleSize = (msb & 0xF0) >> 4;
                Debug.Assert(dwordMultipleSize == 3);         // the fat header is 3 dwords

                _maxStackSize = reader.ReadUInt16();

                int codeSize = reader.ReadInt32();
                int localSig = reader.ReadInt32();

                flags = (MethodBodyFlags)((msb & 0x0F) << 8 | lsb);

                _code = ReadCode(method, context, reader, codeSize);

                if ((flags & MethodBodyFlags.MoreSects) != 0)
                {
                    sehBlocks = ReadSehBlocks(reader);
                }

                bool hasGenericVars;
                _vars = context.ResolveLocalVariables(method, localSig, out hasGenericVars);

                if (hasGenericVars)
                {
                    _genericFlags |= GenericFlags.HasGenericVars;
                }
            }
            break;

            case MethodBodyFlags.TinyFormat:
            case MethodBodyFlags.TinyFormat1:
            {
                int codeSize = (lsb >> 2);
                _code = ReadCode(method, context, reader, codeSize);
            }
            break;

            default:
                throw new NotSupportedException("Not supported method body format!");
            }

            TranslateOffsets();

            if (sehBlocks != null)
            {
                _protectedBlocks = TranslateSehBlocks(method, context, sehBlocks, _code);
            }

            context.LinkDebugInfo(this);
        }