Search in sources :

Example 11 with BlockNode

use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.

the class BlockFinallyExtract method mergeReturns.

private static boolean mergeReturns(MethodNode mth, Set<BlocksPair> outs) {
    Set<BlockNode> rightOuts = new HashSet<BlockNode>();
    boolean allReturns = true;
    for (BlocksPair outPair : outs) {
        BlockNode first = outPair.getFirst();
        if (!first.isReturnBlock()) {
            allReturns = false;
        }
        rightOuts.add(outPair.getSecond());
    }
    if (!allReturns || rightOuts.size() != 1) {
        return false;
    }
    Iterator<BlocksPair> it = outs.iterator();
    while (it.hasNext()) {
        BlocksPair out = it.next();
        BlockNode returnBlock = out.getFirst();
        if (!returnBlock.contains(AFlag.ORIG_RETURN)) {
            markForRemove(mth, returnBlock);
            it.remove();
        }
    }
    return true;
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) BlocksPair(jadx.core.dex.visitors.blocksmaker.helpers.BlocksPair) HashSet(java.util.HashSet)

Example 12 with BlockNode

use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.

the class BlockFinish method visit.

@Override
public void visit(MethodNode mth) {
    if (mth.isNoCode()) {
        return;
    }
    for (BlockNode block : mth.getBasicBlocks()) {
        block.updateCleanSuccessors();
        initBlocksInIfNodes(block);
        fixSplitterBlock(block);
    }
    mth.finishBasicBlocks();
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode)

Example 13 with BlockNode

use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.

the class ModVisitor method removeStep.

/**
	 * Remove unnecessary instructions
	 */
private static void removeStep(MethodNode mth, InstructionRemover remover) {
    for (BlockNode block : mth.getBasicBlocks()) {
        remover.setBlock(block);
        for (InsnNode insn : block.getInstructions()) {
            switch(insn.getType()) {
                case NOP:
                case GOTO:
                case NEW_INSTANCE:
                    remover.add(insn);
                    break;
                default:
                    break;
            }
        }
        remover.perform();
    }
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode)

Example 14 with BlockNode

use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.

the class BlockProcessor method splitReturn.

/**
	 * Splice return block if several predecessors presents
	 */
private static boolean splitReturn(MethodNode mth) {
    if (mth.getExitBlocks().size() != 1) {
        return false;
    }
    BlockNode exitBlock = mth.getExitBlocks().get(0);
    if (exitBlock.getInstructions().size() != 1 || exitBlock.contains(AFlag.SYNTHETIC)) {
        return false;
    }
    List<BlockNode> preds = exitBlock.getPredecessors();
    if (preds.size() < 2) {
        return false;
    }
    preds = BlockUtils.filterPredecessors(exitBlock);
    if (preds.size() < 2) {
        return false;
    }
    InsnNode returnInsn = exitBlock.getInstructions().get(0);
    if (returnInsn.getArgsCount() != 0 && !isReturnArgAssignInPred(preds, returnInsn)) {
        return false;
    }
    boolean first = true;
    for (BlockNode pred : preds) {
        BlockNode newRetBlock = BlockSplitter.startNewBlock(mth, exitBlock.getStartOffset());
        newRetBlock.add(AFlag.SYNTHETIC);
        InsnNode newRetInsn;
        if (first) {
            newRetInsn = returnInsn;
            newRetBlock.add(AFlag.ORIG_RETURN);
            first = false;
        } else {
            newRetInsn = duplicateReturnInsn(returnInsn);
        }
        newRetBlock.getInstructions().add(newRetInsn);
        removeConnection(pred, exitBlock);
        connect(pred, newRetBlock);
    }
    cleanExitNodes(mth);
    return true;
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) InsnNode(jadx.core.dex.nodes.InsnNode)

Example 15 with BlockNode

use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.

the class BlockProcessor method computeDominators.

private static void computeDominators(MethodNode mth) {
    List<BlockNode> basicBlocks = mth.getBasicBlocks();
    int nBlocks = basicBlocks.size();
    for (int i = 0; i < nBlocks; i++) {
        BlockNode block = basicBlocks.get(i);
        block.setId(i);
        block.setDoms(new BitSet(nBlocks));
        block.getDoms().set(0, nBlocks);
    }
    BlockNode entryBlock = mth.getEnterBlock();
    entryBlock.getDoms().clear();
    entryBlock.getDoms().set(entryBlock.getId());
    BitSet dset = new BitSet(nBlocks);
    boolean changed;
    do {
        changed = false;
        for (BlockNode block : basicBlocks) {
            if (block == entryBlock) {
                continue;
            }
            BitSet d = block.getDoms();
            if (!changed) {
                dset.clear();
                dset.or(d);
            }
            for (BlockNode pred : block.getPredecessors()) {
                d.and(pred.getDoms());
            }
            d.set(block.getId());
            if (!changed && !d.equals(dset)) {
                changed = true;
            }
        }
    } while (changed);
    markLoops(mth);
    // clear self dominance
    for (BlockNode block : basicBlocks) {
        block.getDoms().clear(block.getId());
    }
    // calculate immediate dominators
    for (BlockNode block : basicBlocks) {
        if (block == entryBlock) {
            continue;
        }
        BlockNode idom;
        List<BlockNode> preds = block.getPredecessors();
        if (preds.size() == 1) {
            idom = preds.get(0);
        } else {
            BitSet bs = new BitSet(block.getDoms().length());
            bs.or(block.getDoms());
            for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1)) {
                BlockNode dom = basicBlocks.get(i);
                bs.andNot(dom.getDoms());
            }
            if (bs.cardinality() != 1) {
                throw new JadxRuntimeException("Can't find immediate dominator for block " + block + " in " + bs + " preds:" + preds);
            }
            idom = basicBlocks.get(bs.nextSetBit(0));
        }
        block.setIDom(idom);
        idom.addDominatesOn(block);
    }
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) BitSet(java.util.BitSet) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException)

Aggregations

BlockNode (jadx.core.dex.nodes.BlockNode)220 InsnNode (jadx.core.dex.nodes.InsnNode)91 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)43 ArrayList (java.util.ArrayList)41 BitSet (java.util.BitSet)31 JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)29 InsnArg (jadx.core.dex.instructions.args.InsnArg)25 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)21 ExceptionHandler (jadx.core.dex.trycatch.ExceptionHandler)19 PhiInsn (jadx.core.dex.instructions.PhiInsn)14 SSAVar (jadx.core.dex.instructions.args.SSAVar)14 Nullable (org.jetbrains.annotations.Nullable)14 LoopInfo (jadx.core.dex.attributes.nodes.LoopInfo)13 IRegion (jadx.core.dex.nodes.IRegion)13 HashSet (java.util.HashSet)13 MethodNode (jadx.core.dex.nodes.MethodNode)12 Region (jadx.core.dex.regions.Region)12 LoopRegion (jadx.core.dex.regions.loops.LoopRegion)12 InsnType (jadx.core.dex.instructions.InsnType)11 SynchronizedRegion (jadx.core.dex.regions.SynchronizedRegion)11