private void processExcHandler(ExceptionHandler handler, Set<BlockNode> exits) { BlockNode start = handler.getHandlerBlock(); if (start == null) { return; } RegionStack stack = new RegionStack(mth); BlockNode dom; if (handler.isFinally()) { SplitterBlockAttr splitterAttr = start.get(AType.SPLITTER_BLOCK); if (splitterAttr == null) { return; } dom = splitterAttr.getBlock(); } else { dom = start; stack.addExits(exits); } BitSet domFrontier = dom.getDomFrontier(); List<BlockNode> handlerExits = BlockUtils.bitSetToBlocks(mth, domFrontier); boolean inLoop = mth.getLoopForBlock(start) != null; for (BlockNode exit : handlerExits) { if ((!inLoop || BlockUtils.isPathExists(start, exit)) && RegionUtils.isRegionContainsBlock(mth.getRegion(), exit)) { stack.addExit(exit); } } handler.setHandlerRegion(makeRegion(start, stack)); ExcHandlerAttr excHandlerAttr = start.get(AType.EXC_HANDLER); if (excHandlerAttr == null) { LOG.warn("Missing exception handler attribute for start block"); } else { handler.getHandlerRegion().addAttr(excHandlerAttr); } }
private static boolean removePhiList(MethodNode mth, List<PhiInsn> insnToRemove) { if (insnToRemove.isEmpty()) { return false; } 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()) { 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; }
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] = mth.makeNewSVar(regNum, vers, result); } } for (BlockNode s : block.getSuccessors()) { PhiListAttr phiList = s.get(AType.PHI_LIST); if (phiList == null) { continue; } int j = s.getPredecessors().indexOf(block); if (j == -1) { throw new JadxRuntimeException("Can't find predecessor for " + block + " " + s); } for (PhiInsn phiInsn : phiList.getList()) { if (j >= phiInsn.getArgsCount()) { continue; } int regNum = phiInsn.getResult().getRegNum(); SSAVar var = vars[regNum]; if (var == null) { continue; } var.use(phiInsn.getArg(j)); var.setUsedInPhi(phiInsn); } } for (BlockNode domOn : block.getDominatesOn()) { renameVar(mth, vars, vers, domOn); } System.arraycopy(inputVars, 0, vars, 0, vars.length); }
private static void addPhi(BlockNode block, int regNum) { PhiListAttr phiList = block.get(AType.PHI_LIST); if (phiList == null) { phiList = new PhiListAttr(); block.addAttr(phiList); } PhiInsn phiInsn = new PhiInsn(regNum, block.getPredecessors().size()); phiList.getList().add(phiInsn); phiInsn.setOffset(block.getStartOffset()); block.getInstructions().add(0, phiInsn); }
private static void fixLastTryCatchAssign(MethodNode mth) { for (BlockNode block : mth.getBasicBlocks()) { PhiListAttr phiList = block.get(AType.PHI_LIST); if (phiList == null || !block.contains(AType.EXC_HANDLER)) { continue; } 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.getResult() != null && parentInsn.contains(AFlag.TRY_LEAVE)) { phi.removeArg(arg); } } } } }
private static boolean removeUselessPhi(MethodNode mth) { List<PhiInsn> insnToRemove = new ArrayList<PhiInsn>(); for (SSAVar var : mth.getSVars()) { // phi result not used if (var.getUseCount() == 0) { InsnNode assignInsn = var.getAssign().getParentInsn(); if (assignInsn != null && assignInsn.getType() == InsnType.PHI) { insnToRemove.add((PhiInsn) assignInsn); } } } for (BlockNode block : mth.getBasicBlocks()) { PhiListAttr phiList = block.get(AType.PHI_LIST); if (phiList == null) { continue; } for (PhiInsn phi : phiList.getList()) { removePhiWithSameArgs(phi, insnToRemove); } } return removePhiList(mth, insnToRemove); }