Beispiel #1
0
 public virtual Instruction GetLastInstruction()
 {
     if (seq.IsEmpty())
     {
         return(null);
     }
     else
     {
         return(seq.GetLastInstr());
     }
 }
Beispiel #2
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;
         }
     }
 }
Beispiel #3
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;
         }
     }
 }