Search in sources :

Example 16 with LoopInfo

use of jadx.core.dex.attributes.nodes.LoopInfo in project jadx by skylot.

the class RegionMaker method insertLoopBreak.

private boolean insertLoopBreak(RegionStack stack, LoopInfo loop, BlockNode loopExit, Edge exitEdge) {
    BlockNode exit = exitEdge.getTarget();
    Edge insertEdge = null;
    boolean confirm = false;
    // process special cases:
    // 1. jump to outer loop
    BlockNode exitEnd = BlockUtils.followEmptyPath(exit);
    List<LoopInfo> loops = exitEnd.getAll(AType.LOOP);
    for (LoopInfo loopAtEnd : loops) {
        if (loopAtEnd != loop) {
            insertEdge = exitEdge;
            confirm = true;
            break;
        }
    }
    if (!confirm) {
        BlockNode insertBlock = null;
        while (exit != null) {
            if (insertBlock != null && isPathExists(loopExit, exit)) {
                // found cross
                if (canInsertBreak(insertBlock)) {
                    insertEdge = new Edge(insertBlock, insertBlock.getSuccessors().get(0));
                    confirm = true;
                    break;
                }
                return false;
            }
            insertBlock = exit;
            List<BlockNode> cs = exit.getCleanSuccessors();
            exit = cs.size() == 1 ? cs.get(0) : null;
        }
    }
    if (!confirm) {
        return false;
    }
    InsnNode breakInsn = new InsnNode(InsnType.BREAK, 0);
    breakInsn.addAttr(AType.LOOP, loop);
    EdgeInsnAttr.addEdgeInsn(insertEdge, breakInsn);
    stack.addExit(exit);
    // add label to 'break' if needed
    addBreakLabel(exitEdge, exit, breakInsn);
    return true;
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) InsnNode(jadx.core.dex.nodes.InsnNode) LoopInfo(jadx.core.dex.attributes.nodes.LoopInfo) Edge(jadx.core.dex.nodes.Edge)

Example 17 with LoopInfo

use of jadx.core.dex.attributes.nodes.LoopInfo in project jadx by skylot.

the class RegionMaker method makeLoopRegion.

/**
 * Select loop exit and construct LoopRegion
 */
private LoopRegion makeLoopRegion(IRegion curRegion, LoopInfo loop, List<BlockNode> exitBlocks) {
    for (BlockNode block : exitBlocks) {
        if (block.contains(AType.EXC_HANDLER)) {
            continue;
        }
        InsnNode lastInsn = BlockUtils.getLastInsn(block);
        if (lastInsn == null || lastInsn.getType() != InsnType.IF) {
            continue;
        }
        List<LoopInfo> loops = block.getAll(AType.LOOP);
        if (!loops.isEmpty() && loops.get(0) != loop) {
            // skip nested loop condition
            continue;
        }
        LoopRegion loopRegion = new LoopRegion(curRegion, loop, block, block == loop.getEnd());
        boolean found;
        if (block == loop.getStart() || block == loop.getEnd() || BlockUtils.isEmptySimplePath(loop.getStart(), block)) {
            found = true;
        } else if (block.getPredecessors().contains(loop.getStart())) {
            loopRegion.setPreCondition(loop.getStart());
            // if we can't merge pre-condition this is not correct header
            found = loopRegion.checkPreCondition();
        } else {
            found = false;
        }
        if (found) {
            List<LoopInfo> list = mth.getAllLoopsForBlock(block);
            if (list.size() >= 2) {
                // bad condition if successors going out of all loops
                boolean allOuter = true;
                for (BlockNode outerBlock : block.getCleanSuccessors()) {
                    List<LoopInfo> outLoopList = mth.getAllLoopsForBlock(outerBlock);
                    outLoopList.remove(loop);
                    if (!outLoopList.isEmpty()) {
                        // goes to outer loop
                        allOuter = false;
                        break;
                    }
                }
                if (allOuter) {
                    found = false;
                }
            }
        }
        if (found && !checkLoopExits(loop, block)) {
            found = false;
        }
        if (found) {
            return loopRegion;
        }
    }
    // no exit found => endless loop
    return null;
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) InsnNode(jadx.core.dex.nodes.InsnNode) LoopInfo(jadx.core.dex.attributes.nodes.LoopInfo) LoopRegion(jadx.core.dex.regions.loops.LoopRegion)

Aggregations

LoopInfo (jadx.core.dex.attributes.nodes.LoopInfo)17 BlockNode (jadx.core.dex.nodes.BlockNode)12 InsnNode (jadx.core.dex.nodes.InsnNode)5 ArrayList (java.util.ArrayList)5 LoopRegion (jadx.core.dex.regions.loops.LoopRegion)4 JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)4 LoopLabelAttr (jadx.core.dex.attributes.nodes.LoopLabelAttr)3 Edge (jadx.core.dex.nodes.Edge)3 IRegion (jadx.core.dex.nodes.IRegion)3 Region (jadx.core.dex.regions.Region)3 SwitchRegion (jadx.core.dex.regions.SwitchRegion)3 SynchronizedRegion (jadx.core.dex.regions.SynchronizedRegion)3 IfRegion (jadx.core.dex.regions.conditions.IfRegion)3 IfNode (jadx.core.dex.instructions.IfNode)2 InsnType (jadx.core.dex.instructions.InsnType)2 SwitchInsn (jadx.core.dex.instructions.SwitchInsn)2 ExceptionHandler (jadx.core.dex.trycatch.ExceptionHandler)2 BitSet (java.util.BitSet)2 LinkedHashMap (java.util.LinkedHashMap)2 List (java.util.List)2