Search in sources :

Example 91 with BlockNode

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

the class SSATransform method renameVariables.

private static void renameVariables(MethodNode mth) {
    RenameState initState = RenameState.init(mth);
    initPhiInEnterBlock(initState);
    Deque<RenameState> stack = new LinkedList<>();
    stack.push(initState);
    while (!stack.isEmpty()) {
        RenameState state = stack.pop();
        renameVarsInBlock(mth, state);
        for (BlockNode dominated : state.getBlock().getDominatesOn()) {
            stack.push(RenameState.copyFrom(state, dominated));
        }
    }
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) LinkedList(java.util.LinkedList)

Example 92 with BlockNode

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

the class SSATransform method placePhi.

private static void placePhi(MethodNode mth, int regNum, LiveVarAnalysis la) {
    List<BlockNode> blocks = mth.getBasicBlocks();
    int blocksCount = blocks.size();
    BitSet hasPhi = new BitSet(blocksCount);
    BitSet processed = new BitSet(blocksCount);
    Deque<BlockNode> workList = new LinkedList<>();
    BitSet assignBlocks = la.getAssignBlocks(regNum);
    for (int id = assignBlocks.nextSetBit(0); id >= 0; id = assignBlocks.nextSetBit(id + 1)) {
        processed.set(id);
        workList.add(blocks.get(id));
    }
    while (!workList.isEmpty()) {
        BlockNode block = workList.pop();
        BitSet domFrontier = block.getDomFrontier();
        for (int id = domFrontier.nextSetBit(0); id >= 0; id = domFrontier.nextSetBit(id + 1)) {
            if (!hasPhi.get(id) && la.isLive(id, regNum)) {
                BlockNode df = blocks.get(id);
                addPhi(mth, df, regNum);
                hasPhi.set(id);
                if (!processed.get(id)) {
                    processed.set(id);
                    workList.add(df);
                }
            }
        }
    }
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) BitSet(java.util.BitSet) LinkedList(java.util.LinkedList)

Example 93 with BlockNode

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

the class SSATransform method renameVarsInBlock.

private static void renameVarsInBlock(MethodNode mth, RenameState state) {
    BlockNode block = state.getBlock();
    for (InsnNode insn : block.getInstructions()) {
        if (insn.getType() != InsnType.PHI) {
            for (InsnArg arg : insn.getArguments()) {
                if (!arg.isRegister()) {
                    continue;
                }
                RegisterArg reg = (RegisterArg) arg;
                int regNum = reg.getRegNum();
                SSAVar var = state.getVar(regNum);
                if (var == null) {
                    // TODO: in most cases issue in incorrectly attached exception handlers
                    mth.addWarnComment("Not initialized variable reg: " + regNum + ", insn: " + insn + ", block:" + block);
                    var = state.startVar(reg);
                }
                var.use(reg);
            }
        }
        RegisterArg result = insn.getResult();
        if (result != null) {
            state.startVar(result);
        }
    }
    for (BlockNode s : block.getSuccessors()) {
        PhiListAttr phiList = s.get(AType.PHI_LIST);
        if (phiList == null) {
            continue;
        }
        for (PhiInsn phiInsn : phiList.getList()) {
            bindPhiArg(state, phiInsn);
        }
    }
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) SSAVar(jadx.core.dex.instructions.args.SSAVar) PhiInsn(jadx.core.dex.instructions.PhiInsn) InsnArg(jadx.core.dex.instructions.args.InsnArg) PhiListAttr(jadx.core.dex.attributes.nodes.PhiListAttr)

Example 94 with BlockNode

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

the class SSATransform method removeBlockerInsns.

private static boolean removeBlockerInsns(MethodNode mth) {
    boolean removed = false;
    for (BlockNode block : mth.getBasicBlocks()) {
        PhiListAttr phiList = block.get(AType.PHI_LIST);
        if (phiList == null) {
            continue;
        }
        // check if args must be removed
        for (PhiInsn phi : phiList.getList()) {
            for (int i = 0; i < phi.getArgsCount(); i++) {
                RegisterArg arg = phi.getArg(i);
                InsnNode parentInsn = arg.getAssignInsn();
                if (parentInsn != null && parentInsn.contains(AFlag.REMOVE)) {
                    phi.removeArg(arg);
                    InsnRemover.remove(mth, block, parentInsn);
                    removed = true;
                }
            }
        }
    }
    return removed;
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) PhiInsn(jadx.core.dex.instructions.PhiInsn) PhiListAttr(jadx.core.dex.attributes.nodes.PhiListAttr)

Example 95 with BlockNode

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

the class IfMakerHelper method restructureIf.

static IfInfo restructureIf(MethodNode mth, BlockNode block, IfInfo info) {
    BlockNode thenBlock = info.getThenBlock();
    BlockNode elseBlock = info.getElseBlock();
    if (Objects.equals(thenBlock, elseBlock)) {
        IfInfo ifInfo = new IfInfo(info, null, null);
        ifInfo.setOutBlock(thenBlock);
        return ifInfo;
    }
    // select 'then', 'else' and 'exit' blocks
    if (thenBlock.contains(AFlag.RETURN) && elseBlock.contains(AFlag.RETURN)) {
        info.setOutBlock(null);
        return info;
    }
    boolean badThen = isBadBranchBlock(info, thenBlock);
    boolean badElse = isBadBranchBlock(info, elseBlock);
    if (badThen && badElse) {
        LOG.debug("Stop processing blocks after 'if': {}, method: {}", info.getMergedBlocks(), mth);
        return null;
    }
    if (badElse) {
        info = new IfInfo(info, thenBlock, null);
        info.setOutBlock(elseBlock);
    } else if (badThen) {
        info = IfInfo.invert(info);
        info = new IfInfo(info, elseBlock, null);
        info.setOutBlock(thenBlock);
    } else {
        info.setOutBlock(BlockUtils.getPathCross(mth, thenBlock, elseBlock));
    }
    if (BlockUtils.isBackEdge(block, info.getOutBlock())) {
        info.setOutBlock(null);
    }
    return info;
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) IfInfo(jadx.core.dex.regions.conditions.IfInfo)

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