Esempio n. 1
0
        public virtual void BuildMonitorFlags()
        {
            foreach (Statement st in stats)
            {
                st.BuildMonitorFlags();
            }
            switch (type)
            {
            case Type_Basicblock:
            {
                BasicBlockStatement bblock = (BasicBlockStatement)this;
                InstructionSequence seq    = bblock.GetBlock().GetSeq();
                if (seq != null && seq.Length() > 0)
                {
                    for (int i = 0; i < seq.Length(); i++)
                    {
                        if (seq.GetInstr(i).opcode == ICodeConstants.opc_monitorexit)
                        {
                            containsMonitorExit = true;
                            break;
                        }
                    }
                    isMonitorEnter__ = (seq.GetLastInstr().opcode == ICodeConstants.opc_monitorenter);
                }
                break;
            }

            case Type_Sequence:
            case Type_If:
            {
                containsMonitorExit = false;
                foreach (Statement st in stats)
                {
                    containsMonitorExit |= st.IsContainsMonitorExit();
                }
                break;
            }

            case Type_Syncronized:
            case Type_Root:
            case Type_General:
            {
                break;
            }

            default:
            {
                containsMonitorExit = false;
                foreach (Statement st in stats)
                {
                    containsMonitorExit |= st.IsContainsMonitorExit();
                }
                break;
            }
            }
        }
Esempio n. 2
0
 public virtual Instruction GetLastInstruction()
 {
     if (seq.IsEmpty())
     {
         return(null);
     }
     else
     {
         return(seq.GetLastInstr());
     }
 }
Esempio n. 3
0
 public static void MergeBasicBlocks(ControlFlowGraph graph)
 {
     while (true)
     {
         bool merged = false;
         foreach (BasicBlock block in graph.GetBlocks())
         {
             InstructionSequence seq = block.GetSeq();
             if (block.GetSuccs().Count == 1)
             {
                 BasicBlock next = block.GetSuccs()[0];
                 if (next != graph.GetLast() && (seq.IsEmpty() || seq.GetLastInstr().group != ICodeConstants
                                                 .Group_Switch))
                 {
                     if (next.GetPreds().Count == 1 && (next.GetPredExceptions().Count == 0) && next !=
                         graph.GetFirst())
                     {
                         // TODO: implement a dummy start block
                         bool sameRanges = true;
                         foreach (ExceptionRangeCFG range in graph.GetExceptions())
                         {
                             if (range.GetProtectedRange().Contains(block) ^ range.GetProtectedRange().Contains
                                     (next))
                             {
                                 sameRanges = false;
                                 break;
                             }
                         }
                         if (sameRanges)
                         {
                             seq.AddSequence(next.GetSeq());
                             Sharpen.Collections.AddAll(block.GetInstrOldOffsets(), next.GetInstrOldOffsets());
                             next.GetSeq().Clear();
                             RemoveEmptyBlock(graph, next, true);
                             merged = true;
                             break;
                         }
                     }
                 }
             }
         }
         if (!merged)
         {
             break;
         }
     }
 }
Esempio n. 4
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);
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
 }
Esempio n. 5
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;
         }
     }
 }