Beispiel #1
0
        public ILStructure(MethodBody body)
            : this(ILStructureType.Root, 0, body.CodeSize)
        {
            // Build the tree of exception structures:
            foreach (ExceptionHandler eh in body.ExceptionHandlers)
            {
                AddNestedStructure(new ILStructure(ILStructureType.Try, eh.TryStart.Offset, eh.TryEnd.Offset, eh));
                if (eh.HandlerType == ExceptionHandlerType.Filter)
                {
                    AddNestedStructure(new ILStructure(ILStructureType.Filter, eh.FilterStart.Offset, eh.HandlerStart.Offset, eh));
                }
                AddNestedStructure(new ILStructure(ILStructureType.Handler, eh.HandlerStart.Offset, eh.HandlerEnd == null ? body.CodeSize : eh.HandlerEnd.Offset, eh));
            }
            // Very simple loop detection: look for backward branches
            List <KeyValuePair <Instruction, Instruction> > allBranches = FindAllBranches(body);

            // We go through the branches in reverse so that we find the biggest possible loop boundary first (think loops with "continue;")
            for (int i = allBranches.Count - 1; i >= 0; i--)
            {
                int loopEnd   = allBranches[i].Key.GetEndOffset();
                int loopStart = allBranches[i].Value.Offset;
                if (loopStart < loopEnd)
                {
                    // We found a backward branch. This is a potential loop.
                    // Check that is has only one entry point:
                    Instruction entryPoint = null;

                    // entry point is first instruction in loop if prev inst isn't an unconditional branch
                    Instruction prev = allBranches[i].Value.Previous;
                    if (prev != null && !OpCodeInfo.IsUnconditionalBranch(prev.OpCode))
                    {
                        entryPoint = allBranches[i].Value;
                    }

                    bool multipleEntryPoints = false;
                    foreach (var pair in allBranches)
                    {
                        if (pair.Key.Offset < loopStart || pair.Key.Offset >= loopEnd)
                        {
                            if (loopStart <= pair.Value.Offset && pair.Value.Offset < loopEnd)
                            {
                                // jump from outside the loop into the loop
                                if (entryPoint == null)
                                {
                                    entryPoint = pair.Value;
                                }
                                else if (pair.Value != entryPoint)
                                {
                                    multipleEntryPoints = true;
                                }
                            }
                        }
                    }
                    if (!multipleEntryPoints)
                    {
                        AddNestedStructure(new ILStructure(ILStructureType.Loop, loopStart, loopEnd, entryPoint));
                    }
                }
            }
            SortChildren();
        }
Beispiel #2
0
        public IlStructure(MethodBody body, int codesize) : this(IlStructureType.Root, 0, codesize)
        {
            // Build the tree of exception structures:
            for (var i = 0; i < body.ExceptionHandlers.Count; i++)
            {
                var eh = body.ExceptionHandlers[i];
                if (!body.ExceptionHandlers.Take(i).Any(oldEh => oldEh.TryStart == eh.TryStart && oldEh.TryEnd == eh.TryEnd))
                {
                    AddNestedStructure(new IlStructure(IlStructureType.Try, eh.TryStart.Offset, eh.TryEnd.Offset, eh));
                }
                if (eh.HandlerType == ExceptionHandlerType.Filter)
                {
                    AddNestedStructure(new IlStructure(IlStructureType.Filter, eh.FilterStart.Offset, eh.HandlerStart.Offset, eh));
                }
                AddNestedStructure(new IlStructure(IlStructureType.Handler, eh.HandlerStart.Offset, eh.HandlerEnd?.Offset ?? codesize, eh));
            }
            // Very simple loop detection: look for backward branches
            var allBranches = FindAllBranches(body);

            // We go through the branches in reverse so that we find the biggest possible loop boundary first (think loops with "continue;")
            for (var i = allBranches.Count - 1; i >= 0; i--)
            {
                var loopEnd   = allBranches[i].Key.Offset + allBranches[i].Key.GetSize();
                var loopStart = allBranches[i].Value.Offset;

                if (loopStart >= loopEnd)
                {
                    continue;
                }

                // We found a backward branch. This is a potential loop.
                // Check that is has only one entry point:
                Instruction entryPoint = null;

                // entry point is first instruction in loop if prev inst isn't an unconditional branch
                var prev = allBranches[i].Value.Previous;
                if (prev != null && !OpCodeInfo.IsUnconditionalBranch(prev.OpCode))
                {
                    entryPoint = allBranches[i].Value;
                }

                var multipleEntryPoints = false;
                foreach (var pair in allBranches)
                {
                    if (pair.Key.Offset >= loopStart && pair.Key.Offset < loopEnd)
                    {
                        continue;
                    }
                    if (loopStart > pair.Value.Offset || pair.Value.Offset >= loopEnd)
                    {
                        continue;
                    }

                    // jump from outside the loop into the loop
                    if (entryPoint == null)
                    {
                        entryPoint = pair.Value;
                    }
                    else if (pair.Value != entryPoint)
                    {
                        multipleEntryPoints = true;
                    }
                }
                if (!multipleEntryPoints)
                {
                    AddNestedStructure(new IlStructure(IlStructureType.Loop, loopStart, loopEnd, entryPoint));
                }
            }
            SortChildren();
        }