Search in sources :

Example 26 with SSAVar

use of jadx.core.dex.instructions.args.SSAVar in project jadx by skylot.

the class EliminatePhiNodes method replaceMerge.

/**
	 * Replace 'MERGE' with 'PHI' insn.
	 */
private void replaceMerge(MethodNode mth, BlockNode block, InsnNode insn) {
    if (insn.getArgsCount() != 2) {
        throw new JadxRuntimeException("Unexpected count of arguments in merge insn: " + insn);
    }
    RegisterArg oldArg = (RegisterArg) insn.getArg(1);
    RegisterArg newArg = (RegisterArg) insn.getArg(0);
    int newRegNum = newArg.getRegNum();
    if (oldArg.getRegNum() == newRegNum) {
        throw new JadxRuntimeException("Unexpected register number in merge insn: " + insn);
    }
    SSAVar oldSVar = oldArg.getSVar();
    RegisterArg assignArg = oldSVar.getAssign();
    InsnNode assignParentInsn = assignArg.getParentInsn();
    BlockNode assignBlock = BlockUtils.getBlockByInsn(mth, assignParentInsn);
    if (assignBlock == null) {
        throw new JadxRuntimeException("Unknown assign block for " + assignParentInsn);
    }
    BlockNode assignPred = null;
    for (BlockNode pred : block.getPredecessors()) {
        if (BlockUtils.isPathExists(assignBlock, pred)) {
            assignPred = pred;
            break;
        }
    }
    if (assignPred == null) {
        throw new JadxRuntimeException("Assign predecessor not found for " + assignBlock + " from " + block);
    }
    // all checks passed
    RegisterArg newAssignArg = oldArg.duplicate(newRegNum, null);
    SSAVar newSVar = mth.makeNewSVar(newRegNum, mth.getNextSVarVersion(newRegNum), newAssignArg);
    newSVar.setName(oldSVar.getName());
    newSVar.setType(assignArg.getType());
    if (assignParentInsn != null) {
        assignParentInsn.setResult(newAssignArg);
    }
    for (RegisterArg useArg : oldSVar.getUseList()) {
        RegisterArg newUseArg = useArg.duplicate(newRegNum, newSVar);
        InsnNode parentInsn = useArg.getParentInsn();
        if (parentInsn != null) {
            newSVar.use(newUseArg);
            parentInsn.replaceArg(useArg, newUseArg);
        }
    }
    block.getInstructions().remove(0);
    PhiInsn phiInsn = SSATransform.addPhi(mth, block, newRegNum);
    phiInsn.setResult(insn.getResult());
    phiInsn.bindArg(newAssignArg.duplicate(), assignPred);
    phiInsn.bindArg(newArg.duplicate(), BlockUtils.selectOtherSafe(assignPred, block.getPredecessors()));
}
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) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException)

Example 27 with SSAVar

use of jadx.core.dex.instructions.args.SSAVar in project jadx by skylot.

the class SSATransform method initPhiInEnterBlock.

private static void initPhiInEnterBlock(SSAVar[] vars, BlockNode enterBlock) {
    PhiListAttr phiList = enterBlock.get(AType.PHI_LIST);
    if (phiList != null) {
        for (PhiInsn phiInsn : phiList.getList()) {
            int regNum = phiInsn.getResult().getRegNum();
            SSAVar var = vars[regNum];
            if (var == null) {
                continue;
            }
            RegisterArg arg = phiInsn.bindArg(enterBlock);
            var.use(arg);
            var.setUsedInPhi(phiInsn);
        }
    }
}
Also used : RegisterArg(jadx.core.dex.instructions.args.RegisterArg) PhiInsn(jadx.core.dex.instructions.PhiInsn) SSAVar(jadx.core.dex.instructions.args.SSAVar) PhiListAttr(jadx.core.dex.attributes.nodes.PhiListAttr)

Example 28 with SSAVar

use of jadx.core.dex.instructions.args.SSAVar in project jadx by skylot.

the class SSATransform method removePhiList.

private static boolean removePhiList(MethodNode mth, List<PhiInsn> insnToRemove) {
    for (BlockNode block : mth.getBasicBlocks()) {
        PhiListAttr phiList = block.get(AType.PHI_LIST);
        if (phiList == null) {
            continue;
        }
        List<PhiInsn> list = phiList.getList();
        for (PhiInsn phiInsn : insnToRemove) {
            if (list.remove(phiInsn)) {
                for (InsnArg arg : phiInsn.getArguments()) {
                    if (arg == null) {
                        continue;
                    }
                    SSAVar sVar = ((RegisterArg) arg).getSVar();
                    if (sVar != null) {
                        sVar.setUsedInPhi(null);
                    }
                }
                InstructionRemover.remove(mth, block, phiInsn);
            }
        }
        if (list.isEmpty()) {
            block.remove(AType.PHI_LIST);
        }
    }
    insnToRemove.clear();
    return true;
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) 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)

Aggregations

SSAVar (jadx.core.dex.instructions.args.SSAVar)28 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)22 InsnNode (jadx.core.dex.nodes.InsnNode)16 InsnArg (jadx.core.dex.instructions.args.InsnArg)9 PhiInsn (jadx.core.dex.instructions.PhiInsn)7 BlockNode (jadx.core.dex.nodes.BlockNode)7 ArgType (jadx.core.dex.instructions.args.ArgType)6 PhiListAttr (jadx.core.dex.attributes.nodes.PhiListAttr)5 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)5 ArrayList (java.util.ArrayList)5 JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)4 LiteralArg (jadx.core.dex.instructions.args.LiteralArg)3 FieldNode (jadx.core.dex.nodes.FieldNode)2 MethodNode (jadx.core.dex.nodes.MethodNode)2 ForEachLoop (jadx.core.dex.regions.loops.ForEachLoop)2 MethodParameters (jadx.core.dex.attributes.annotations.MethodParameters)1 FieldReplaceAttr (jadx.core.dex.attributes.nodes.FieldReplaceAttr)1 AccessInfo (jadx.core.dex.info.AccessInfo)1 ClassInfo (jadx.core.dex.info.ClassInfo)1 MethodInfo (jadx.core.dex.info.MethodInfo)1