Search in sources :

Example 61 with RegisterArg

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

the class BlockFinallyExtract method sameInsns.

private static boolean sameInsns(InsnNode remInsn, InsnNode fInsn, BlocksRemoveInfo removeInfo) {
    if (!remInsn.isSame(fInsn)) {
        return false;
    }
    // TODO: compare literals
    for (int i = 0; i < remInsn.getArgsCount(); i++) {
        InsnArg remArg = remInsn.getArg(i);
        InsnArg fArg = fInsn.getArg(i);
        if (remArg.isRegister() != fArg.isRegister()) {
            return false;
        }
        if (removeInfo != null && fArg.isRegister()) {
            RegisterArg remReg = (RegisterArg) remArg;
            RegisterArg fReg = (RegisterArg) fArg;
            if (remReg.getRegNum() != fReg.getRegNum()) {
                RegisterArg mapReg = removeInfo.getRegMap().get(remArg);
                if (mapReg == null) {
                    removeInfo.getRegMap().put(remReg, fReg);
                } else if (!mapReg.equalRegisterAndType(fReg)) {
                    return false;
                }
            }
        }
    }
    return true;
}
Also used : RegisterArg(jadx.core.dex.instructions.args.RegisterArg) InsnArg(jadx.core.dex.instructions.args.InsnArg)

Example 62 with RegisterArg

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

the class BlockFinallyExtract method performVariablesReMap.

private static void performVariablesReMap(MethodNode mth, List<BlocksRemoveInfo> removes, LiveVarAnalysis laBefore, LiveVarAnalysis laAfter) {
    BitSet processed = new BitSet(mth.getRegsCount());
    for (BlocksRemoveInfo removeInfo : removes) {
        processed.clear();
        BlocksPair start = removeInfo.getStart();
        BlockNode insertBlockBefore = start.getFirst();
        BlockNode insertBlock = start.getSecond();
        if (removeInfo.getRegMap().isEmpty() || insertBlock == null) {
            continue;
        }
        for (Map.Entry<RegisterArg, RegisterArg> entry : removeInfo.getRegMap().entrySet()) {
            RegisterArg fromReg = entry.getKey();
            RegisterArg toReg = entry.getValue();
            int fromRegNum = fromReg.getRegNum();
            int toRegNum = toReg.getRegNum();
            if (!processed.get(fromRegNum)) {
                boolean liveFromBefore = laBefore.isLive(insertBlockBefore, fromRegNum);
                boolean liveFromAfter = laAfter.isLive(insertBlock, fromRegNum);
                // boolean liveToBefore = laBefore.isLive(insertBlock, toRegNum);
                boolean liveToAfter = laAfter.isLive(insertBlock, toRegNum);
                if (liveToAfter && liveFromBefore) {
                    // merge 'to' and 'from' registers
                    InsnNode merge = new InsnNode(InsnType.MERGE, 2);
                    merge.setResult(toReg.duplicate());
                    merge.addArg(toReg.duplicate());
                    merge.addArg(fromReg.duplicate());
                    injectInsn(mth, insertBlock, merge);
                } else if (liveFromBefore) {
                    // remap variable
                    InsnNode move = new InsnNode(InsnType.MOVE, 1);
                    move.setResult(toReg.duplicate());
                    move.addArg(fromReg.duplicate());
                    injectInsn(mth, insertBlock, move);
                } else if (liveFromAfter) {
                    // kill variable
                    InsnNode kill = new InsnNode(InsnType.NOP, 0);
                    kill.setResult(fromReg.duplicate());
                    kill.add(AFlag.REMOVE);
                    injectInsn(mth, insertBlock, kill);
                }
                processed.set(fromRegNum);
            }
        }
    }
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) BitSet(java.util.BitSet) BlocksPair(jadx.core.dex.visitors.blocksmaker.helpers.BlocksPair) Map(java.util.Map) BlocksRemoveInfo(jadx.core.dex.visitors.blocksmaker.helpers.BlocksRemoveInfo)

Example 63 with RegisterArg

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

the class TypeInference method processPhiNode.

private static void processPhiNode(PhiInsn phi) {
    ArgType type = phi.getResult().getType();
    if (!type.isTypeKnown()) {
        for (InsnArg arg : phi.getArguments()) {
            if (arg.getType().isTypeKnown()) {
                type = arg.getType();
                break;
            }
        }
    }
    phi.getResult().setType(type);
    for (int i = 0; i < phi.getArgsCount(); i++) {
        RegisterArg arg = phi.getArg(i);
        arg.setType(type);
        SSAVar sVar = arg.getSVar();
        if (sVar != null) {
            sVar.setName(phi.getResult().getName());
        }
    }
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) SSAVar(jadx.core.dex.instructions.args.SSAVar) InsnArg(jadx.core.dex.instructions.args.InsnArg)

Example 64 with RegisterArg

use of jadx.core.dex.instructions.args.RegisterArg 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 65 with RegisterArg

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

the class LiveVarAnalysis method fillBasicBlockInfo.

private void fillBasicBlockInfo() {
    for (BlockNode block : mth.getBasicBlocks()) {
        int blockId = block.getId();
        BitSet gen = uses[blockId];
        BitSet kill = defs[blockId];
        for (InsnNode insn : block.getInstructions()) {
            for (InsnArg arg : insn.getArguments()) {
                if (arg.isRegister()) {
                    int regNum = ((RegisterArg) arg).getRegNum();
                    if (!kill.get(regNum)) {
                        gen.set(regNum);
                    }
                }
            }
            RegisterArg result = insn.getResult();
            if (result != null) {
                int regNum = result.getRegNum();
                kill.set(regNum);
                assignBlocks[regNum].set(blockId);
            }
        }
    }
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) InsnArg(jadx.core.dex.instructions.args.InsnArg) BitSet(java.util.BitSet)

Aggregations

RegisterArg (jadx.core.dex.instructions.args.RegisterArg)67 InsnNode (jadx.core.dex.nodes.InsnNode)39 InsnArg (jadx.core.dex.instructions.args.InsnArg)24 SSAVar (jadx.core.dex.instructions.args.SSAVar)22 BlockNode (jadx.core.dex.nodes.BlockNode)17 PhiInsn (jadx.core.dex.instructions.PhiInsn)11 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)10 ArgType (jadx.core.dex.instructions.args.ArgType)8 ArrayList (java.util.ArrayList)8 PhiListAttr (jadx.core.dex.attributes.nodes.PhiListAttr)6 JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)6 MethodNode (jadx.core.dex.nodes.MethodNode)4 MethodInfo (jadx.core.dex.info.MethodInfo)3 ConstClassNode (jadx.core.dex.instructions.ConstClassNode)3 LiteralArg (jadx.core.dex.instructions.args.LiteralArg)3 ConstructorInsn (jadx.core.dex.instructions.mods.ConstructorInsn)3 ClassNode (jadx.core.dex.nodes.ClassNode)3 FieldNode (jadx.core.dex.nodes.FieldNode)3 IContainer (jadx.core.dex.nodes.IContainer)3 ExceptionHandler (jadx.core.dex.trycatch.ExceptionHandler)3