use of jadx.core.utils.exceptions.JadxRuntimeException in project jadx by skylot.
the class IfMakerHelper method getCrossBlock.
private static BlockNode getCrossBlock(BlockNode first, BlockNode second) {
if (isSameBlocks(first, second)) {
return second;
}
BlockNode firstSkip = BlockUtils.skipSyntheticSuccessor(first);
if (isSameBlocks(firstSkip, second)) {
return second;
}
BlockNode secondSkip = BlockUtils.skipSyntheticSuccessor(second);
if (isSameBlocks(firstSkip, secondSkip) || isSameBlocks(first, secondSkip)) {
return secondSkip;
}
throw new JadxRuntimeException("Unexpected merge pattern");
}
use of jadx.core.utils.exceptions.JadxRuntimeException in project jadx by skylot.
the class BlockFinallyExtract method applyRemove.
private static boolean applyRemove(MethodNode mth, BlocksRemoveInfo removeInfo) {
BlockNode remBlock = removeInfo.getStart().getFirst();
BlockNode startBlock = removeInfo.getStart().getSecond();
if (remBlock.contains(AFlag.REMOVE)) {
// already processed
return true;
}
if (remBlock.getPredecessors().size() != 1) {
LOG.warn("Finally extract failed: remBlock pred: {}, {}, method: {}", remBlock, remBlock.getPredecessors(), mth);
return false;
}
BlockNode remBlockPred = remBlock.getPredecessors().get(0);
removeInfo.setStartPredecessor(remBlockPred);
int startSplitIndex = removeInfo.getStartSplitIndex();
int endSplitIndex = removeInfo.getEndSplitIndex();
if (removeInfo.getStart().equals(removeInfo.getEnd())) {
removeInfo.setEndSplitIndex(endSplitIndex - startSplitIndex);
}
// split start block (remBlock)
if (startSplitIndex > 0) {
remBlock = splitBlock(mth, remBlock, startSplitIndex);
// change start block in removeInfo
removeInfo.getProcessed().remove(removeInfo.getStart());
BlocksPair newStart = new BlocksPair(remBlock, startBlock);
// removeInfo.setStart(newStart);
removeInfo.getProcessed().add(newStart);
}
// split end block
if (endSplitIndex > 0) {
BlocksPair end = removeInfo.getEnd();
BlockNode newOut = splitBlock(mth, end.getFirst(), endSplitIndex);
for (BlockNode s : newOut.getSuccessors()) {
BlocksPair replaceOut = null;
Iterator<BlocksPair> it = removeInfo.getOuts().iterator();
while (it.hasNext()) {
BlocksPair outPair = it.next();
if (outPair.getFirst().equals(s)) {
it.remove();
replaceOut = new BlocksPair(newOut, outPair.getSecond());
break;
}
}
if (replaceOut != null) {
removeInfo.getOuts().add(replaceOut);
}
}
}
BlocksPair out = removeInfo.getOuts().iterator().next();
BlockNode rOut = out.getFirst();
BlockNode sOut = out.getSecond();
// redirect out edges
List<BlockNode> filtPreds = BlockUtils.filterPredecessors(sOut);
if (filtPreds.size() > 1) {
BlockNode pred = sOut.getPredecessors().get(0);
BlockNode newPred = BlockSplitter.insertBlockBetween(mth, pred, sOut);
for (BlockNode predBlock : new ArrayList<BlockNode>(sOut.getPredecessors())) {
if (predBlock != newPred) {
removeConnection(predBlock, sOut);
connect(predBlock, newPred);
}
}
rOut.getPredecessors().clear();
addIgnoredEdge(newPred, rOut);
connect(newPred, rOut);
} else if (filtPreds.size() == 1) {
BlockNode pred = filtPreds.get(0);
BlockNode repl = removeInfo.getBySecond(pred);
if (repl == null) {
LOG.error("Block not found by {}, in {}, method: {}", pred, removeInfo, mth);
return false;
}
removeConnection(pred, rOut);
addIgnoredEdge(repl, rOut);
connect(repl, rOut);
} else {
throw new JadxRuntimeException("Finally extract failed, unexpected preds: " + filtPreds + " for " + sOut + ", method: " + mth);
}
// redirect input edges
for (BlockNode pred : new ArrayList<BlockNode>(remBlock.getPredecessors())) {
BlockNode middle = insertBlockBetween(mth, pred, remBlock);
removeConnection(middle, remBlock);
connect(middle, startBlock);
addIgnoredEdge(middle, startBlock);
connect(middle, rOut);
}
// mark blocks for remove
markForRemove(mth, remBlock);
for (BlocksPair pair : removeInfo.getProcessed()) {
markForRemove(mth, pair.getFirst());
BlockNode second = pair.getSecond();
second.updateCleanSuccessors();
}
return true;
}
use of jadx.core.utils.exceptions.JadxRuntimeException in project jadx by skylot.
the class ExportGradleProject method init.
public void init() {
try {
FileUtils.makeDirsForFile(srcOutDir);
FileUtils.makeDirsForFile(resOutDir);
saveBuildGradle();
skipGeneratedClasses();
} catch (Exception e) {
throw new JadxRuntimeException("Gradle export failed", e);
}
}
use of jadx.core.utils.exceptions.JadxRuntimeException 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()));
}
use of jadx.core.utils.exceptions.JadxRuntimeException in project jadx by skylot.
the class LiveVarAnalysis method processLiveInfo.
private void processLiveInfo() {
int bbCount = mth.getBasicBlocks().size();
int regsCount = mth.getRegsCount();
BitSet[] liveIn = initBitSetArray(bbCount, regsCount);
List<BlockNode> blocks = mth.getBasicBlocks();
int blocksSize = blocks.size();
boolean changed;
int k = 0;
do {
changed = false;
for (int i = 0; i < blocksSize; i++) {
BlockNode block = blocks.get(i);
int blockId = block.getId();
BitSet prevIn = liveIn[blockId];
BitSet newIn = new BitSet(regsCount);
List<BlockNode> successors = block.getSuccessors();
for (int s = 0, successorsSize = successors.size(); s < successorsSize; s++) {
newIn.or(liveIn[successors.get(s).getId()]);
}
newIn.andNot(defs[blockId]);
newIn.or(uses[blockId]);
if (!prevIn.equals(newIn)) {
changed = true;
liveIn[blockId] = newIn;
}
}
if (k++ > 1000) {
throw new JadxRuntimeException("Live variable analysis reach iterations limit");
}
} while (changed);
this.liveIn = liveIn;
}
Aggregations