Пример #1
0
 private static bool SplitExceptionRange(ExceptionRangeCFG range, HashSet <BasicBlock
                                                                           > setEntries, ControlFlowGraph graph, GenericDominatorEngine engine)
 {
     foreach (BasicBlock entry in setEntries)
     {
         List <BasicBlock> lstSubrangeBlocks = GetReachableBlocksRestricted(entry, range,
                                                                            engine);
         if (!(lstSubrangeBlocks.Count == 0) && lstSubrangeBlocks.Count < range.GetProtectedRange
                 ().Count)
         {
             // add new range
             ExceptionRangeCFG subRange = new ExceptionRangeCFG(lstSubrangeBlocks, range.GetHandler
                                                                    (), range.GetExceptionTypes());
             graph.GetExceptions().Add(subRange);
             // shrink the original range
             lstSubrangeBlocks.ForEach(block => range.GetProtectedRange().Remove(block));
             return(true);
         }
         else
         {
             // should not happen
             DecompilerContext.GetLogger().WriteMessage("Inconsistency found while splitting protected range"
                                                        , IFernflowerLogger.Severity.Warn);
         }
     }
     return(false);
 }
Пример #2
0
        public static void RemoveCircularRanges(ControlFlowGraph graph)
        {
            GenericDominatorEngine engine = new GenericDominatorEngine(new _IIGraph_215(graph
                                                                                        ));

            engine.Initialize();
            List <ExceptionRangeCFG> lstRanges = graph.GetExceptions();

            for (int i = lstRanges.Count - 1; i >= 0; i--)
            {
                ExceptionRangeCFG range     = lstRanges[i];
                BasicBlock        handler   = range.GetHandler();
                List <BasicBlock> rangeList = range.GetProtectedRange();
                if (rangeList.Contains(handler))
                {
                    // TODO: better removing strategy
                    List <BasicBlock> lstRemBlocks = GetReachableBlocksRestricted(range.GetHandler(),
                                                                                  range, engine);
                    if (lstRemBlocks.Count < rangeList.Count || rangeList.Count == 1)
                    {
                        foreach (BasicBlock block in lstRemBlocks)
                        {
                            block.RemoveSuccessorException(handler);
                            rangeList.Remove(block);
                        }
                    }
                    if ((rangeList.Count == 0))
                    {
                        lstRanges.RemoveAtReturningValue(i);
                    }
                }
            }
        }
Пример #3
0
        private static void InsertBlockBefore(ControlFlowGraph graph, BasicBlock oldblock
                                              , BasicBlock newblock)
        {
            List <BasicBlock> lstTemp = new List <BasicBlock>();

            Sharpen.Collections.AddAll(lstTemp, oldblock.GetPreds());
            Sharpen.Collections.AddAll(lstTemp, oldblock.GetPredExceptions());
            // replace predecessors
            foreach (BasicBlock pred in lstTemp)
            {
                pred.ReplaceSuccessor(oldblock, newblock);
            }
            // copy exception edges and extend protected ranges
            foreach (BasicBlock hd in oldblock.GetSuccExceptions())
            {
                newblock.AddSuccessorException(hd);
                ExceptionRangeCFG range = graph.GetExceptionRange(hd, oldblock);
                range.GetProtectedRange().Add(newblock);
            }
            // replace handler
            foreach (ExceptionRangeCFG range in graph.GetExceptions())
            {
                if (range.GetHandler() == oldblock)
                {
                    range.SetHandler(newblock);
                }
            }
            newblock.AddSuccessor(oldblock);
            graph.GetBlocks().AddWithKey(newblock, newblock.id);
            if (graph.GetFirst() == oldblock)
            {
                graph.SetFirst(newblock);
            }
        }
Пример #4
0
        public static void RemoveEmptyRanges(ControlFlowGraph graph)
        {
            List <ExceptionRangeCFG> lstRanges = graph.GetExceptions();

            for (int i = lstRanges.Count - 1; i >= 0; i--)
            {
                ExceptionRangeCFG range = lstRanges[i];
                bool isEmpty            = true;
                foreach (BasicBlock block in range.GetProtectedRange())
                {
                    if (!block.GetSeq().IsEmpty())
                    {
                        isEmpty = false;
                        break;
                    }
                }
                if (isEmpty)
                {
                    foreach (BasicBlock block in range.GetProtectedRange())
                    {
                        block.RemoveSuccessorException(range.GetHandler());
                    }
                    lstRanges.RemoveAtReturningValue(i);
                }
            }
        }
Пример #5
0
        public static void InsertDummyExceptionHandlerBlocks(ControlFlowGraph graph, int
                                                             bytecode_version)
        {
            Dictionary <BasicBlock, HashSet <ExceptionRangeCFG> > mapRanges = new Dictionary <BasicBlock
                                                                                              , HashSet <ExceptionRangeCFG> >();

            foreach (ExceptionRangeCFG range in graph.GetExceptions())
            {
                mapRanges.ComputeIfAbsent(range.GetHandler(), (BasicBlock k) => new HashSet <ExceptionRangeCFG
                                                                                             >()).Add(range);
            }
            foreach (KeyValuePair <BasicBlock, HashSet <ExceptionRangeCFG> > ent in mapRanges)
            {
                BasicBlock handler = ent.Key;
                HashSet <ExceptionRangeCFG> ranges = ent.Value;
                if (ranges.Count == 1)
                {
                    continue;
                }
                foreach (ExceptionRangeCFG range in ranges)
                {
                    // add some dummy instructions to prevent optimizing away the empty block
                    SimpleInstructionSequence seq = new SimpleInstructionSequence();
                    seq.AddInstruction(Instruction.Create(ICodeConstants.opc_bipush, false, ICodeConstants
                                                          .Group_General, bytecode_version, new int[] { 0 }), -1);
                    seq.AddInstruction(Instruction.Create(ICodeConstants.opc_pop, false, ICodeConstants
                                                          .Group_General, bytecode_version, null), -1);
                    BasicBlock dummyBlock = new BasicBlock(++graph.last_id);
                    dummyBlock.SetSeq(seq);
                    graph.GetBlocks().AddWithKey(dummyBlock, dummyBlock.id);
                    // only exception predecessors from this range considered
                    List <BasicBlock> lstPredExceptions = new List <BasicBlock>(handler.GetPredExceptions
                                                                                    ());
                    lstPredExceptions = lstPredExceptions.Intersect(range.GetProtectedRange()).ToList();
                    // replace predecessors
                    foreach (BasicBlock pred in lstPredExceptions)
                    {
                        pred.ReplaceSuccessor(handler, dummyBlock);
                    }
                    // replace handler
                    range.SetHandler(dummyBlock);
                    // add common exception edges
                    HashSet <BasicBlock> commonHandlers = new HashSet <BasicBlock>(handler.GetSuccExceptions
                                                                                       ());
                    foreach (BasicBlock pred in lstPredExceptions)
                    {
                        commonHandlers.IntersectWith(pred.GetSuccExceptions());
                    }
                    // TODO: more sanity checks?
                    foreach (BasicBlock commonHandler in commonHandlers)
                    {
                        ExceptionRangeCFG commonRange = graph.GetExceptionRange(commonHandler, handler);
                        dummyBlock.AddSuccessorException(commonHandler);
                        commonRange.GetProtectedRange().Add(dummyBlock);
                    }
                    dummyBlock.AddSuccessor(handler);
                }
            }
        }
Пример #6
0
 internal Range(BasicBlock handler, string uniqueStr, HashSet <BasicBlock> protectedRange
                , ExceptionRangeCFG rangeCFG)
 {
     this.handler        = handler;
     this.uniqueStr      = uniqueStr;
     this.protectedRange = protectedRange;
     this.rangeCFG       = rangeCFG;
 }
Пример #7
0
        private static HashSet <BasicBlock> GetRangeEntries(ExceptionRangeCFG range)
        {
            HashSet <BasicBlock> setEntries = new HashSet <BasicBlock>();
            HashSet <BasicBlock> setRange   = new HashSet <BasicBlock>(range.GetProtectedRange());

            foreach (BasicBlock block in range.GetProtectedRange())
            {
                HashSet <BasicBlock> setPreds = new HashSet <BasicBlock>(block.GetPreds());
                setPreds.ExceptWith(setRange);
                if (!(setPreds.Count == 0))
                {
                    setEntries.Add(block);
                }
            }
            return(setEntries);
        }
Пример #8
0
        private static RootStatement GraphToStatement(ControlFlowGraph graph)
        {
            VBStyleCollection <Statement, int>  stats  = new VBStyleCollection <Statement, int>();
            VBStyleCollection <BasicBlock, int> blocks = graph.GetBlocks();

            foreach (BasicBlock block in blocks)
            {
                stats.AddWithKey(new BasicBlockStatement(block), block.id);
            }
            BasicBlock firstblock = graph.GetFirst();
            // head statement
            Statement firstst = stats.GetWithKey(firstblock.id);
            // dummy exit statement
            DummyExitStatement dummyexit = new DummyExitStatement();
            Statement          general;

            if (stats.Count > 1 || firstblock.IsSuccessor(firstblock))
            {
                // multiple basic blocks or an infinite loop of one block
                general = new GeneralStatement(firstst, stats, null);
            }
            else
            {
                // one straightforward basic block
                RootStatement root = new RootStatement(firstst, dummyexit);
                firstst.AddSuccessor(new StatEdge(StatEdge.Type_Break, firstst, dummyexit, root));
                return(root);
            }
            foreach (BasicBlock block in blocks)
            {
                Statement stat = stats.GetWithKey(block.id);
                foreach (BasicBlock succ in block.GetSuccs())
                {
                    Statement stsucc = stats.GetWithKey(succ.id);
                    int       type;
                    if (stsucc == firstst)
                    {
                        type = StatEdge.Type_Continue;
                    }
                    else if (graph.GetFinallyExits().Contains(block))
                    {
                        type   = StatEdge.Type_Finallyexit;
                        stsucc = dummyexit;
                    }
                    else if (succ.id == graph.GetLast().id)
                    {
                        type   = StatEdge.Type_Break;
                        stsucc = dummyexit;
                    }
                    else
                    {
                        type = StatEdge.Type_Regular;
                    }
                    stat.AddSuccessor(new StatEdge(type, stat, (type == StatEdge.Type_Continue) ? general
                                                 : stsucc, (type == StatEdge.Type_Regular) ? null : general));
                }
                // exceptions edges
                foreach (BasicBlock succex in block.GetSuccExceptions())
                {
                    Statement         stsuccex = stats.GetWithKey(succex.id);
                    ExceptionRangeCFG range    = graph.GetExceptionRange(succex, block);
                    if (!range.IsCircular())
                    {
                        stat.AddSuccessor(new StatEdge(stat, stsuccex, range.GetExceptionTypes()));
                    }
                }
            }
            general.BuildContinueSet();
            general.BuildMonitorFlags();
            return(new RootStatement(general, dummyexit));
        }
Пример #9
0
        private static List <BasicBlock> GetReachableBlocksRestricted(BasicBlock start, ExceptionRangeCFG
                                                                      range, GenericDominatorEngine engine)
        {
            List <BasicBlock>       lstRes     = new List <BasicBlock>();
            LinkedList <BasicBlock> stack      = new LinkedList <BasicBlock>();
            HashSet <BasicBlock>    setVisited = new HashSet <BasicBlock>();

            stack.AddFirst(start);
            while (!(stack.Count == 0))
            {
                BasicBlock block = Sharpen.Collections.RemoveFirst(stack);
                setVisited.Add(block);
                if (range.GetProtectedRange().Contains(block) && engine.IsDominator(block, start))
                {
                    lstRes.Add(block);
                    List <BasicBlock> lstSuccs = new List <BasicBlock>(block.GetSuccs());
                    Sharpen.Collections.AddAll(lstSuccs, block.GetSuccExceptions());
                    foreach (BasicBlock succ in lstSuccs)
                    {
                        if (!setVisited.Contains(succ))
                        {
                            stack.AddLast(succ);
                        }
                    }
                }
            }
            return(lstRes);
        }
Пример #10
0
        private static bool RemoveEmptyBlock(ControlFlowGraph graph, BasicBlock block, bool
                                             merging)
        {
            bool deletedRanges = false;

            if (block.GetSeq().IsEmpty())
            {
                if (block.GetSuccs().Count > 1)
                {
                    if (block.GetPreds().Count > 1)
                    {
                        // ambiguous block
                        throw new Exception("ERROR: empty block with multiple predecessors and successors found"
                                            );
                    }
                    else if (!merging)
                    {
                        throw new Exception("ERROR: empty block with multiple successors found");
                    }
                }
                HashSet <BasicBlock> setExits = new HashSet <BasicBlock>(graph.GetLast().GetPreds()
                                                                         );
                if ((block.GetPredExceptions().Count == 0) && (!setExits.Contains(block) || block
                                                               .GetPreds().Count == 1))
                {
                    if (setExits.Contains(block))
                    {
                        BasicBlock pred = block.GetPreds()[0];
                        // FIXME: flag in the basic block
                        if (pred.GetSuccs().Count != 1 || (!pred.GetSeq().IsEmpty() && pred.GetSeq().GetLastInstr
                                                               ().group == ICodeConstants.Group_Switch))
                        {
                            return(false);
                        }
                    }
                    HashSet <BasicBlock> setPreds = new HashSet <BasicBlock>(block.GetPreds());
                    HashSet <BasicBlock> setSuccs = new HashSet <BasicBlock>(block.GetSuccs());
                    // collect common exception ranges of predecessors and successors
                    HashSet <BasicBlock> setCommonExceptionHandlers = null;
                    for (int i = 0; i < 2; ++i)
                    {
                        foreach (BasicBlock pred in i == 0 ? setPreds : setSuccs)
                        {
                            if (setCommonExceptionHandlers == null)
                            {
                                setCommonExceptionHandlers = new HashSet <BasicBlock>(pred.GetSuccExceptions());
                            }
                            else
                            {
                                setCommonExceptionHandlers.IntersectWith(pred.GetSuccExceptions());
                            }
                        }
                    }
                    // check the block to be in each of the common ranges
                    if (setCommonExceptionHandlers != null && !(setCommonExceptionHandlers.Count == 0))
                    {
                        foreach (BasicBlock handler in setCommonExceptionHandlers)
                        {
                            if (!block.GetSuccExceptions().Contains(handler))
                            {
                                return(false);
                            }
                        }
                    }
                    // remove ranges consisting of this one block
                    List <ExceptionRangeCFG> lstRanges = graph.GetExceptions();
                    for (int i = lstRanges.Count - 1; i >= 0; i--)
                    {
                        ExceptionRangeCFG range = lstRanges[i];
                        List <BasicBlock> lst   = range.GetProtectedRange();
                        if (lst.Count == 1 && lst[0] == block)
                        {
                            if (DecompilerContext.GetOption(IFernflowerPreferences.Remove_Empty_Ranges))
                            {
                                block.RemoveSuccessorException(range.GetHandler());
                                lstRanges.RemoveAtReturningValue(i);
                                deletedRanges = true;
                            }
                            else
                            {
                                return(false);
                            }
                        }
                    }
                    // connect remaining nodes
                    if (merging)
                    {
                        BasicBlock pred = block.GetPreds()[0];
                        pred.RemoveSuccessor(block);
                        List <BasicBlock> lstSuccs = new List <BasicBlock>(block.GetSuccs());
                        foreach (BasicBlock succ in lstSuccs)
                        {
                            block.RemoveSuccessor(succ);
                            pred.AddSuccessor(succ);
                        }
                    }
                    else
                    {
                        foreach (BasicBlock pred in setPreds)
                        {
                            foreach (BasicBlock succ in setSuccs)
                            {
                                pred.ReplaceSuccessor(block, succ);
                            }
                        }
                    }
                    // finally exit edges
                    HashSet <BasicBlock> setFinallyExits = graph.GetFinallyExits();
                    if (setFinallyExits.Contains(block))
                    {
                        setFinallyExits.Remove(block);
                        setFinallyExits.Add(new Sharpen.EnumeratorAdapter <BasicBlock>(setPreds.GetEnumerator()).Next());
                    }
                    // replace first if necessary
                    if (graph.GetFirst() == block)
                    {
                        if (setSuccs.Count != 1)
                        {
                            throw new Exception("multiple or no entry blocks!");
                        }
                        else
                        {
                            graph.SetFirst(new Sharpen.EnumeratorAdapter <BasicBlock>(setSuccs.GetEnumerator()).Next());
                        }
                    }
                    // remove this block
                    graph.RemoveBlock(block);
                    if (deletedRanges)
                    {
                        RemoveDeadBlocks(graph);
                    }
                }
            }
            return(deletedRanges);
        }
Пример #11
0
 public static void IncorporateValueReturns(ControlFlowGraph graph)
 {
     foreach (BasicBlock block in graph.GetBlocks())
     {
         InstructionSequence seq = block.GetSeq();
         int len = seq.Length();
         if (len > 0 && len < 3)
         {
             bool ok = false;
             if (seq.GetLastInstr().opcode >= ICodeConstants.opc_ireturn && seq.GetLastInstr()
                 .opcode <= ICodeConstants.opc_return)
             {
                 if (len == 1)
                 {
                     ok = true;
                 }
                 else if (seq.GetLastInstr().opcode != ICodeConstants.opc_return)
                 {
                     switch (seq.GetInstr(0).opcode)
                     {
                     case ICodeConstants.opc_iload:
                     case ICodeConstants.opc_lload:
                     case ICodeConstants.opc_fload:
                     case ICodeConstants.opc_dload:
                     case ICodeConstants.opc_aload:
                     case ICodeConstants.opc_aconst_null:
                     case ICodeConstants.opc_bipush:
                     case ICodeConstants.opc_sipush:
                     case ICodeConstants.opc_lconst_0:
                     case ICodeConstants.opc_lconst_1:
                     case ICodeConstants.opc_fconst_0:
                     case ICodeConstants.opc_fconst_1:
                     case ICodeConstants.opc_fconst_2:
                     case ICodeConstants.opc_dconst_0:
                     case ICodeConstants.opc_dconst_1:
                     case ICodeConstants.opc_ldc:
                     case ICodeConstants.opc_ldc_w:
                     case ICodeConstants.opc_ldc2_w:
                     {
                         ok = true;
                         break;
                     }
                     }
                 }
             }
             if (ok)
             {
                 if (!(block.GetPreds().Count == 0))
                 {
                     HashSet <BasicBlock> setPredHandlersUnion        = new HashSet <BasicBlock>();
                     HashSet <BasicBlock> setPredHandlersIntersection = new HashSet <BasicBlock>();
                     bool firstpred = true;
                     foreach (BasicBlock pred in block.GetPreds())
                     {
                         if (firstpred)
                         {
                             Sharpen.Collections.AddAll(setPredHandlersIntersection, pred.GetSuccExceptions());
                             firstpred = false;
                         }
                         else
                         {
                             setPredHandlersIntersection.IntersectWith(pred.GetSuccExceptions());
                         }
                         Sharpen.Collections.AddAll(setPredHandlersUnion, pred.GetSuccExceptions());
                     }
                     // add exception ranges from predecessors
                     setPredHandlersIntersection.ExceptWith(block.GetSuccExceptions());
                     BasicBlock predecessor = block.GetPreds()[0];
                     foreach (BasicBlock handler in setPredHandlersIntersection)
                     {
                         ExceptionRangeCFG range = graph.GetExceptionRange(handler, predecessor);
                         range.GetProtectedRange().Add(block);
                         block.AddSuccessorException(handler);
                     }
                     // remove redundant ranges
                     HashSet <BasicBlock> setRangesToBeRemoved = new HashSet <BasicBlock>(block.GetSuccExceptions
                                                                                              ());
                     setRangesToBeRemoved.ExceptWith(setPredHandlersUnion);
                     foreach (BasicBlock handler in setRangesToBeRemoved)
                     {
                         ExceptionRangeCFG range = graph.GetExceptionRange(handler, block);
                         if (range.GetProtectedRange().Count > 1)
                         {
                             range.GetProtectedRange().Remove(block);
                             block.RemoveSuccessorException(handler);
                         }
                     }
                 }
                 if (block.GetPreds().Count == 1 && (block.GetPredExceptions().Count == 0))
                 {
                     BasicBlock bpred = block.GetPreds()[0];
                     if (bpred.GetSuccs().Count == 1)
                     {
                         // add exception ranges of predecessor
                         foreach (BasicBlock succ in bpred.GetSuccExceptions())
                         {
                             if (!block.GetSuccExceptions().Contains(succ))
                             {
                                 ExceptionRangeCFG range = graph.GetExceptionRange(succ, bpred);
                                 range.GetProtectedRange().Add(block);
                                 block.AddSuccessorException(succ);
                             }
                         }
                         // remove superfluous ranges from successors
                         foreach (BasicBlock succ in new HashSet <BasicBlock>(block.GetSuccExceptions()))
                         {
                             if (!bpred.GetSuccExceptions().Contains(succ))
                             {
                                 ExceptionRangeCFG range = graph.GetExceptionRange(succ, block);
                                 if (range.GetProtectedRange().Count > 1)
                                 {
                                     range.GetProtectedRange().Remove(block);
                                     block.RemoveSuccessorException(succ);
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
 }
Пример #12
0
 public static void ExtendSynchronizedRangeToMonitorexit(ControlFlowGraph graph)
 {
     while (true)
     {
         bool range_extended = false;
         foreach (ExceptionRangeCFG range in graph.GetExceptions())
         {
             HashSet <BasicBlock> setPreds = new HashSet <BasicBlock>();
             foreach (BasicBlock block in range.GetProtectedRange())
             {
                 Sharpen.Collections.AddAll(setPreds, block.GetPreds());
             }
             setPreds.ExceptWith(range.GetProtectedRange());
             if (setPreds.Count != 1)
             {
                 continue;
             }
             // multiple predecessors, obfuscated range
             var                 setPredsEnumerator = new EnumeratorAdapter <BasicBlock>(setPreds.GetEnumerator());
             BasicBlock          predBlock          = setPredsEnumerator.Next();
             InstructionSequence predSeq            = predBlock.GetSeq();
             if (predSeq.IsEmpty() || predSeq.GetLastInstr().opcode != ICodeConstants.opc_monitorenter)
             {
                 continue;
             }
             // not a synchronized range
             bool monitorexit_in_range = false;
             HashSet <BasicBlock> setProtectedBlocks = new HashSet <BasicBlock>();
             Sharpen.Collections.AddAll(setProtectedBlocks, range.GetProtectedRange());
             setProtectedBlocks.Add(range.GetHandler());
             foreach (BasicBlock block in setProtectedBlocks)
             {
                 InstructionSequence blockSeq = block.GetSeq();
                 for (int i = 0; i < blockSeq.Length(); i++)
                 {
                     if (blockSeq.GetInstr(i).opcode == ICodeConstants.opc_monitorexit)
                     {
                         monitorexit_in_range = true;
                         break;
                     }
                 }
                 if (monitorexit_in_range)
                 {
                     break;
                 }
             }
             if (monitorexit_in_range)
             {
                 continue;
             }
             // protected range already contains monitorexit
             HashSet <BasicBlock> setSuccs = new HashSet <BasicBlock>();
             foreach (BasicBlock block in range.GetProtectedRange())
             {
                 Sharpen.Collections.AddAll(setSuccs, block.GetSuccs());
             }
             setSuccs.ExceptWith(range.GetProtectedRange());
             if (setSuccs.Count != 1)
             {
                 continue;
             }
             // non-unique successor
             BasicBlock          succBlock = new Sharpen.EnumeratorAdapter <BasicBlock>(setSuccs.GetEnumerator()).Next();
             InstructionSequence succSeq   = succBlock.GetSeq();
             int succ_monitorexit_index    = -1;
             for (int i = 0; i < succSeq.Length(); i++)
             {
                 if (succSeq.GetInstr(i).opcode == ICodeConstants.opc_monitorexit)
                 {
                     succ_monitorexit_index = i;
                     break;
                 }
             }
             if (succ_monitorexit_index < 0)
             {
                 continue;
             }
             // monitorexit not found in the single successor block
             BasicBlock handlerBlock = range.GetHandler();
             if (handlerBlock.GetSuccs().Count != 1)
             {
                 continue;
             }
             // non-unique handler successor
             BasicBlock          succHandler    = handlerBlock.GetSuccs()[0];
             InstructionSequence succHandlerSeq = succHandler.GetSeq();
             if (succHandlerSeq.IsEmpty() || succHandlerSeq.GetLastInstr().opcode != ICodeConstants
                 .opc_athrow)
             {
                 continue;
             }
             // not a standard synchronized range
             int handler_monitorexit_index = -1;
             for (int i = 0; i < succHandlerSeq.Length(); i++)
             {
                 if (succHandlerSeq.GetInstr(i).opcode == ICodeConstants.opc_monitorexit)
                 {
                     handler_monitorexit_index = i;
                     break;
                 }
             }
             if (handler_monitorexit_index < 0)
             {
                 continue;
             }
             // monitorexit not found in the handler successor block
             // checks successful, prerequisites satisfied, now extend the range
             if (succ_monitorexit_index < succSeq.Length() - 1)
             {
                 // split block
                 SimpleInstructionSequence seq = new SimpleInstructionSequence();
                 for (int counter = 0; counter < succ_monitorexit_index; counter++)
                 {
                     seq.AddInstruction(succSeq.GetInstr(0), -1);
                     succSeq.RemoveInstruction(0);
                 }
                 // build a separate block
                 BasicBlock newblock = new BasicBlock(++graph.last_id);
                 newblock.SetSeq(seq);
                 // insert new block
                 foreach (BasicBlock block in succBlock.GetPreds())
                 {
                     block.ReplaceSuccessor(succBlock, newblock);
                 }
                 newblock.AddSuccessor(succBlock);
                 graph.GetBlocks().AddWithKey(newblock, newblock.id);
                 succBlock = newblock;
             }
             // copy exception edges and extend protected ranges (successor block)
             BasicBlock rangeExitBlock = succBlock.GetPreds()[0];
             for (int j = 0; j < rangeExitBlock.GetSuccExceptions().Count; j++)
             {
                 BasicBlock hd = rangeExitBlock.GetSuccExceptions()[j];
                 succBlock.AddSuccessorException(hd);
                 ExceptionRangeCFG rng = graph.GetExceptionRange(hd, rangeExitBlock);
                 rng.GetProtectedRange().Add(succBlock);
             }
             // copy instructions (handler successor block)
             InstructionSequence handlerSeq = handlerBlock.GetSeq();
             for (int counter = 0; counter < handler_monitorexit_index; counter++)
             {
                 handlerSeq.AddInstruction(succHandlerSeq.GetInstr(0), -1);
                 succHandlerSeq.RemoveInstruction(0);
             }
             range_extended = true;
             break;
         }
         if (!range_extended)
         {
             break;
         }
     }
 }
Пример #13
0
        private bool CompareBasicBlocksEx(ControlFlowGraph graph, BasicBlock pattern, BasicBlock
                                          sample, int type, int finallytype, List <int[]> lstStoreVars)
        {
            InstructionSequence seqPattern = pattern.GetSeq();
            InstructionSequence seqSample  = sample.GetSeq();

            if (type != 0)
            {
                seqPattern = seqPattern.Clone();
                if ((type & 1) > 0)
                {
                    // first
                    if (finallytype > 0)
                    {
                        seqPattern.RemoveInstruction(0);
                    }
                }
                if ((type & 2) > 0)
                {
                    // last
                    if (finallytype == 0 || finallytype == 2)
                    {
                        seqPattern.RemoveLast();
                    }
                    if (finallytype == 2)
                    {
                        seqPattern.RemoveLast();
                    }
                }
            }
            if (seqPattern.Length() > seqSample.Length())
            {
                return(false);
            }
            for (int i = 0; i < seqPattern.Length(); i++)
            {
                Instruction instrPattern = seqPattern.GetInstr(i);
                Instruction instrSample  = seqSample.GetInstr(i);
                // compare instructions with respect to jumps
                if (!EqualInstructions(instrPattern, instrSample, lstStoreVars))
                {
                    return(false);
                }
            }
            if (seqPattern.Length() < seqSample.Length())
            {
                // split in two blocks
                SimpleInstructionSequence seq        = new SimpleInstructionSequence();
                LinkedList <int>          oldOffsets = new LinkedList <int>();
                for (int i = seqSample.Length() - 1; i >= seqPattern.Length(); i--)
                {
                    seq.AddInstruction(0, seqSample.GetInstr(i), -1);
                    oldOffsets.AddFirst(sample.GetOldOffset(i));
                    seqSample.RemoveInstruction(i);
                }
                BasicBlock newblock = new BasicBlock(++graph.last_id);
                newblock.SetSeq(seq);
                Sharpen.Collections.AddAll(newblock.GetInstrOldOffsets(), oldOffsets);
                List <BasicBlock> lstTemp = new List <BasicBlock>(sample.GetSuccs());
                // move successors
                foreach (BasicBlock suc in lstTemp)
                {
                    sample.RemoveSuccessor(suc);
                    newblock.AddSuccessor(suc);
                }
                sample.AddSuccessor(newblock);
                graph.GetBlocks().AddWithKey(newblock, newblock.id);
                HashSet <BasicBlock> setFinallyExits = graph.GetFinallyExits();
                if (setFinallyExits.Contains(sample))
                {
                    setFinallyExits.Remove(sample);
                    setFinallyExits.Add(newblock);
                }
                // copy exception edges and extend protected ranges
                for (int j = 0; j < sample.GetSuccExceptions().Count; j++)
                {
                    BasicBlock hd = sample.GetSuccExceptions()[j];
                    newblock.AddSuccessorException(hd);
                    ExceptionRangeCFG range = graph.GetExceptionRange(hd, sample);
                    range.GetProtectedRange().Add(newblock);
                }
            }
            return(true);
        }
Пример #14
0
        private static void InsertSemaphore(ControlFlowGraph graph, HashSet <BasicBlock> setTry
                                            , BasicBlock head, BasicBlock handler, int var, FinallyProcessor.Record information
                                            , int bytecode_version)
        {
            HashSet <BasicBlock> setCopy = new HashSet <BasicBlock>(setTry);
            int finallytype = information.firstCode;
            Dictionary <BasicBlock, bool> mapLast = information.mapLast;

            // first and last statements
            RemoveExceptionInstructionsEx(handler, 1, finallytype);
            foreach (KeyValuePair <BasicBlock, bool> entry in mapLast)
            {
                BasicBlock last = entry.Key;
                if (entry.Value)
                {
                    RemoveExceptionInstructionsEx(last, 2, finallytype);
                    graph.GetFinallyExits().Add(last);
                }
            }
            // disable semaphore at statement exit points
            foreach (BasicBlock block in setTry)
            {
                List <BasicBlock> lstSucc = block.GetSuccs();
                foreach (BasicBlock dest in lstSucc)
                {
                    // break out
                    if (dest != graph.GetLast() && !setCopy.Contains(dest))
                    {
                        // disable semaphore
                        SimpleInstructionSequence seq = new SimpleInstructionSequence();
                        seq.AddInstruction(Instruction.Create(ICodeConstants.opc_bipush, false, ICodeConstants
                                                              .Group_General, bytecode_version, new int[] { 0 }), -1);
                        seq.AddInstruction(Instruction.Create(ICodeConstants.opc_istore, false, ICodeConstants
                                                              .Group_General, bytecode_version, new int[] { var }), -1);
                        // build a separate block
                        BasicBlock newblock = new BasicBlock(++graph.last_id);
                        newblock.SetSeq(seq);
                        // insert between block and dest
                        block.ReplaceSuccessor(dest, newblock);
                        newblock.AddSuccessor(dest);
                        setCopy.Add(newblock);
                        graph.GetBlocks().AddWithKey(newblock, newblock.id);
                        // exception ranges
                        // FIXME: special case synchronized
                        // copy exception edges and extend protected ranges
                        for (int j = 0; j < block.GetSuccExceptions().Count; j++)
                        {
                            BasicBlock hd = block.GetSuccExceptions()[j];
                            newblock.AddSuccessorException(hd);
                            ExceptionRangeCFG range = graph.GetExceptionRange(hd, block);
                            range.GetProtectedRange().Add(newblock);
                        }
                    }
                }
            }
            // enable semaphore at the statement entrance
            SimpleInstructionSequence seq_1 = new SimpleInstructionSequence();

            seq_1.AddInstruction(Instruction.Create(ICodeConstants.opc_bipush, false, ICodeConstants
                                                    .Group_General, bytecode_version, new int[] { 1 }), -1);
            seq_1.AddInstruction(Instruction.Create(ICodeConstants.opc_istore, false, ICodeConstants
                                                    .Group_General, bytecode_version, new int[] { var }), -1);
            BasicBlock newhead = new BasicBlock(++graph.last_id);

            newhead.SetSeq(seq_1);
            InsertBlockBefore(graph, head, newhead);
            // initialize semaphor with false
            seq_1 = new SimpleInstructionSequence();
            seq_1.AddInstruction(Instruction.Create(ICodeConstants.opc_bipush, false, ICodeConstants
                                                    .Group_General, bytecode_version, new int[] { 0 }), -1);
            seq_1.AddInstruction(Instruction.Create(ICodeConstants.opc_istore, false, ICodeConstants
                                                    .Group_General, bytecode_version, new int[] { var }), -1);
            BasicBlock newheadinit = new BasicBlock(++graph.last_id);

            newheadinit.SetSeq(seq_1);
            InsertBlockBefore(graph, newhead, newheadinit);
            setCopy.Add(newhead);
            setCopy.Add(newheadinit);
            foreach (BasicBlock hd in new HashSet <BasicBlock>(newheadinit.GetSuccExceptions()
                                                               ))
            {
                ExceptionRangeCFG range = graph.GetExceptionRange(hd, newheadinit);
                if (setCopy.ContainsAll(range.GetProtectedRange()))
                {
                    newheadinit.RemoveSuccessorException(hd);
                    range.GetProtectedRange().Remove(newheadinit);
                }
            }
        }