use of jadx.core.dex.nodes.BlockNode 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");
}
}
}
}
use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.
the class DebugChecks method checkMethod.
public static void checkMethod(MethodNode mth) {
List<BlockNode> basicBlocks = mth.getBasicBlocks();
if (Utils.isEmpty(basicBlocks)) {
return;
}
for (BlockNode block : basicBlocks) {
for (InsnNode insn : block.getInstructions()) {
checkInsn(mth, insn);
}
}
checkSSAVars(mth);
// checkPHI(mth);
}
use of jadx.core.dex.nodes.BlockNode 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);
}
use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.
the class TypeInferenceVisitor method checkAndSplitConstInsn.
private boolean checkAndSplitConstInsn(MethodNode mth, SSAVar var) {
ArgType type = var.getTypeInfo().getType();
if (type.isTypeKnown() || var.isTypeImmutable()) {
return false;
}
if (var.getUsedInPhi().size() < 2) {
return false;
}
InsnNode assignInsn = var.getAssign().getAssignInsn();
InsnNode constInsn = InsnUtils.checkInsnType(assignInsn, InsnType.CONST);
if (constInsn == null) {
return false;
}
BlockNode blockNode = BlockUtils.getBlockByInsn(mth, constInsn);
if (blockNode == null) {
return false;
}
// for every PHI make separate CONST insn
boolean first = true;
for (PhiInsn phiInsn : var.getUsedInPhi()) {
if (first) {
first = false;
continue;
}
InsnNode copyInsn = constInsn.copyWithNewSsaVar(mth);
copyInsn.add(AFlag.SYNTHETIC);
BlockUtils.insertAfterInsn(blockNode, constInsn, copyInsn);
RegisterArg phiArg = phiInsn.getArgBySsaVar(var);
phiInsn.replaceArg(phiArg, copyInsn.getResult().duplicate());
}
return true;
}
use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.
the class TypeInferenceVisitor method insertAssignCast.
private boolean insertAssignCast(MethodNode mth, SSAVar var, ArgType castType) {
RegisterArg assignArg = var.getAssign();
InsnNode assignInsn = assignArg.getParentInsn();
if (assignInsn == null || assignInsn.getType() == InsnType.PHI) {
return false;
}
BlockNode assignBlock = BlockUtils.getBlockByInsn(mth, assignInsn);
if (assignBlock == null) {
return false;
}
RegisterArg newAssignArg = assignArg.duplicateWithNewSSAVar(mth);
assignInsn.setResult(newAssignArg);
IndexInsnNode castInsn = makeSoftCastInsn(assignArg, newAssignArg, castType);
return BlockUtils.insertAfterInsn(assignBlock, assignInsn, castInsn);
}
Aggregations