public static bool HandleMultipleEntryExceptionRanges(ControlFlowGraph graph) { GenericDominatorEngine engine = new GenericDominatorEngine(new _IIGraph_314(graph )); engine.Initialize(); bool found; while (true) { found = false; bool splitted = false; foreach (ExceptionRangeCFG range in graph.GetExceptions()) { HashSet <BasicBlock> setEntries = GetRangeEntries(range); if (setEntries.Count > 1) { // multiple-entry protected range found = true; if (SplitExceptionRange(range, setEntries, graph, engine)) { splitted = true; break; } } } if (!splitted) { break; } } return(!found); }
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); } } } }
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); }
public virtual void InitDominators() { HashSet <VarVersionNode> roots = new HashSet <VarVersionNode>(); foreach (VarVersionNode node in nodes) { if ((node.preds.Count == 0)) { roots.Add(node); } } engine = new GenericDominatorEngine(new _IIGraph_74(roots)); engine.Initialize(); }
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); }