Search in sources :

Example 1 with PhiListAttr

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

the class EliminatePhiNodes method removePhiInstructions.

private static void removePhiInstructions(MethodNode mth) {
    for (BlockNode block : mth.getBasicBlocks()) {
        PhiListAttr phiList = block.get(AType.PHI_LIST);
        if (phiList == null) {
            continue;
        }
        List<PhiInsn> list = phiList.getList();
        for (PhiInsn phiInsn : list) {
            removeInsn(mth, block, phiInsn);
        }
    }
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) PhiInsn(jadx.core.dex.instructions.PhiInsn) PhiListAttr(jadx.core.dex.attributes.nodes.PhiListAttr)

Example 2 with PhiListAttr

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

the class SSATransform method renameVar.

private static void renameVar(MethodNode mth, SSAVar[] vars, int[] vers, BlockNode block) {
    SSAVar[] inputVars = Arrays.copyOf(vars, vars.length);
    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 = vars[regNum];
                if (var == null) {
                    throw new JadxRuntimeException("Not initialized variable reg: " + regNum + ", insn: " + insn + ", block:" + block + ", method: " + mth);
                }
                var.use(reg);
            }
        }
        RegisterArg result = insn.getResult();
        if (result != null) {
            int regNum = result.getRegNum();
            vars[regNum] = newSSAVar(mth, vers, result, regNum);
        }
    }
    for (BlockNode s : block.getSuccessors()) {
        PhiListAttr phiList = s.get(AType.PHI_LIST);
        if (phiList == null) {
            continue;
        }
        for (PhiInsn phiInsn : phiList.getList()) {
            int regNum = phiInsn.getResult().getRegNum();
            SSAVar var = vars[regNum];
            if (var == null) {
                continue;
            }
            RegisterArg arg = phiInsn.bindArg(block);
            var.use(arg);
            var.setUsedInPhi(phiInsn);
        }
    }
    for (BlockNode domOn : block.getDominatesOn()) {
        renameVar(mth, vars, vers, domOn);
    }
    System.arraycopy(inputVars, 0, vars, 0, vars.length);
}
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) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException)

Example 3 with PhiListAttr

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

the class DebugUtils method checkPHI.

private static void checkPHI(MethodNode mth) {
    for (BlockNode block : mth.getBasicBlocks()) {
        List<PhiInsn> phis = new ArrayList<PhiInsn>();
        for (InsnNode insn : block.getInstructions()) {
            if (insn.getType() == InsnType.PHI) {
                PhiInsn phi = (PhiInsn) insn;
                phis.add(phi);
                if (phi.getArgsCount() != phi.getBlockBinds().size()) {
                    throw new JadxRuntimeException("Incorrect args and binds in PHI");
                }
                if (phi.getArgsCount() == 0) {
                    throw new JadxRuntimeException("No args and binds in PHI");
                }
                for (InsnArg arg : insn.getArguments()) {
                    if (arg instanceof RegisterArg) {
                        BlockNode b = phi.getBlockByArg((RegisterArg) arg);
                        if (b == null) {
                            throw new JadxRuntimeException("Predecessor block not found");
                        }
                    } else {
                        throw new JadxRuntimeException("Not register in phi insn");
                    }
                }
            }
        }
        PhiListAttr phiListAttr = block.get(AType.PHI_LIST);
        if (phiListAttr == null) {
            if (!phis.isEmpty()) {
                throw new JadxRuntimeException("Missing PHI list attribute");
            }
        } else {
            List<PhiInsn> phiList = phiListAttr.getList();
            if (phiList.isEmpty()) {
                throw new JadxRuntimeException("Empty PHI list attribute");
            }
            if (!phis.containsAll(phiList) || !phiList.containsAll(phis)) {
                throw new JadxRuntimeException("Instructions not match");
            }
        }
    }
    for (SSAVar ssaVar : mth.getSVars()) {
        PhiInsn usedInPhi = ssaVar.getUsedInPhi();
        if (usedInPhi != null) {
            boolean found = false;
            for (RegisterArg useArg : ssaVar.getUseList()) {
                InsnNode parentInsn = useArg.getParentInsn();
                if (parentInsn != null && parentInsn == usedInPhi) {
                    found = true;
                }
            }
            if (!found) {
                throw new JadxRuntimeException("Used in phi incorrect");
            }
        }
    }
}
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) SSAVar(jadx.core.dex.instructions.args.SSAVar) InsnArg(jadx.core.dex.instructions.args.InsnArg) PhiListAttr(jadx.core.dex.attributes.nodes.PhiListAttr) ArrayList(java.util.ArrayList) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException)

Example 4 with PhiListAttr

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

the class DebugChecks method checkPHI.

private static void checkPHI(MethodNode mth) {
    for (BlockNode block : mth.getBasicBlocks()) {
        List<PhiInsn> phis = new ArrayList<>();
        for (InsnNode insn : block.getInstructions()) {
            if (insn.getType() == InsnType.PHI) {
                PhiInsn phi = (PhiInsn) insn;
                phis.add(phi);
                if (phi.getArgsCount() == 0) {
                    throw new JadxRuntimeException("No args and binds in PHI");
                }
                for (InsnArg arg : insn.getArguments()) {
                    if (arg instanceof RegisterArg) {
                        BlockNode b = phi.getBlockByArg((RegisterArg) arg);
                        if (b == null) {
                            throw new JadxRuntimeException("Predecessor block not found");
                        }
                    } else {
                        throw new JadxRuntimeException("Not register in phi insn");
                    }
                }
            }
        }
        PhiListAttr phiListAttr = block.get(AType.PHI_LIST);
        if (phiListAttr == null) {
            if (!phis.isEmpty()) {
                throw new JadxRuntimeException("Missing PHI list attribute");
            }
        } else {
            List<PhiInsn> phiList = phiListAttr.getList();
            if (phiList.isEmpty()) {
                throw new JadxRuntimeException("Empty PHI list attribute");
            }
            if (!phis.containsAll(phiList) || !phiList.containsAll(phis)) {
                throw new JadxRuntimeException("Instructions not match");
            }
        }
    }
    for (SSAVar ssaVar : mth.getSVars()) {
        for (PhiInsn usedInPhi : ssaVar.getUsedInPhi()) {
            boolean found = false;
            for (RegisterArg useArg : ssaVar.getUseList()) {
                InsnNode parentInsn = useArg.getParentInsn();
                if (parentInsn != null && parentInsn == usedInPhi) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                throw new JadxRuntimeException("Used in phi incorrect");
            }
        }
    }
}
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) SSAVar(jadx.core.dex.instructions.args.SSAVar) InsnArg(jadx.core.dex.instructions.args.InsnArg) PhiListAttr(jadx.core.dex.attributes.nodes.PhiListAttr) ArrayList(java.util.ArrayList) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException)

Example 5 with PhiListAttr

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

the class TypeInferenceVisitor method tryInsertAdditionalMove.

private boolean tryInsertAdditionalMove(MethodNode mth) {
    int insnsAdded = 0;
    for (BlockNode block : mth.getBasicBlocks()) {
        PhiListAttr phiListAttr = block.get(AType.PHI_LIST);
        if (phiListAttr != null) {
            for (PhiInsn phiInsn : phiListAttr.getList()) {
                insnsAdded += tryInsertAdditionalInsn(mth, phiInsn);
            }
        }
    }
    if (insnsAdded == 0) {
        return false;
    }
    if (Consts.DEBUG_TYPE_INFERENCE) {
        mth.addDebugComment("Additional " + insnsAdded + " move instructions added to help type inference");
    }
    InitCodeVariables.rerun(mth);
    initTypeBounds(mth);
    if (runTypePropagation(mth) && checkTypes(mth)) {
        return true;
    }
    return tryDeduceTypes(mth);
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) PhiInsn(jadx.core.dex.instructions.PhiInsn) PhiListAttr(jadx.core.dex.attributes.nodes.PhiListAttr)

Aggregations

PhiListAttr (jadx.core.dex.attributes.nodes.PhiListAttr)11 PhiInsn (jadx.core.dex.instructions.PhiInsn)11 BlockNode (jadx.core.dex.nodes.BlockNode)9 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)8 SSAVar (jadx.core.dex.instructions.args.SSAVar)7 InsnNode (jadx.core.dex.nodes.InsnNode)6 InsnArg (jadx.core.dex.instructions.args.InsnArg)5 JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)3 ArrayList (java.util.ArrayList)3