use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.
the class BlockProcessor method cleanExitNodes.
private static void cleanExitNodes(MethodNode mth) {
Iterator<BlockNode> iterator = mth.getExitBlocks().iterator();
while (iterator.hasNext()) {
BlockNode exitBlock = iterator.next();
if (exitBlock.getPredecessors().isEmpty()) {
mth.getBasicBlocks().remove(exitBlock);
iterator.remove();
}
}
}
use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.
the class BlockProcessor method modifyBlocksTree.
private static boolean modifyBlocksTree(MethodNode mth) {
for (BlockNode block : mth.getBasicBlocks()) {
if (block.getPredecessors().isEmpty() && block != mth.getEnterBlock()) {
throw new JadxRuntimeException("Unreachable block: " + block);
}
// check loops
List<LoopInfo> loops = block.getAll(AType.LOOP);
if (loops.size() > 1) {
boolean oneHeader = true;
for (LoopInfo loop : loops) {
if (loop.getStart() != block) {
oneHeader = false;
break;
}
}
if (oneHeader) {
// several back edges connected to one loop header => make additional block
BlockNode newLoopHeader = BlockSplitter.startNewBlock(mth, block.getStartOffset());
newLoopHeader.add(AFlag.SYNTHETIC);
connect(newLoopHeader, block);
for (LoopInfo la : loops) {
BlockNode node = la.getEnd();
removeConnection(node, block);
connect(node, newLoopHeader);
}
return true;
}
}
if (loops.size() == 1) {
LoopInfo loop = loops.get(0);
// insert additional blocks for possible 'break' insertion
List<Edge> edges = loop.getExitEdges();
if (!edges.isEmpty()) {
boolean change = false;
for (Edge edge : edges) {
BlockNode target = edge.getTarget();
if (!target.contains(AFlag.SYNTHETIC)) {
BlockSplitter.insertBlockBetween(mth, edge.getSource(), target);
change = true;
}
}
if (change) {
return true;
}
}
// insert additional blocks for possible 'continue' insertion
BlockNode loopEnd = loop.getEnd();
if (loopEnd.getPredecessors().size() > 1) {
boolean change = false;
List<BlockNode> nodes = new ArrayList<BlockNode>(loopEnd.getPredecessors());
for (BlockNode pred : nodes) {
if (!pred.contains(AFlag.SYNTHETIC)) {
BlockSplitter.insertBlockBetween(mth, pred, loopEnd);
change = true;
}
}
if (change) {
return true;
}
}
}
}
return splitReturn(mth);
}
use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.
the class BlockProcessor method removeBlocks.
private static void removeBlocks(MethodNode mth) {
Iterator<BlockNode> it = mth.getBasicBlocks().iterator();
while (it.hasNext()) {
BlockNode block = it.next();
if (block.contains(AFlag.REMOVE)) {
if (!block.getPredecessors().isEmpty() || !block.getSuccessors().isEmpty()) {
LOG.error("Block {} not deleted, method: {}", block, mth);
} else {
CatchAttr catchAttr = block.get(AType.CATCH_BLOCK);
if (catchAttr != null) {
catchAttr.getTryBlock().removeBlock(mth, block);
}
it.remove();
}
}
}
}
use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.
the class BlockProcessor method isReturnArgAssignInPred.
private static boolean isReturnArgAssignInPred(List<BlockNode> preds, InsnNode returnInsn) {
RegisterArg arg = (RegisterArg) returnInsn.getArg(0);
int regNum = arg.getRegNum();
for (BlockNode pred : preds) {
for (InsnNode insnNode : pred.getInstructions()) {
RegisterArg result = insnNode.getResult();
if (result != null && result.getRegNum() == regNum) {
return true;
}
}
}
return false;
}
use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.
the class BlockSplitter method setupConnections.
private static void setupConnections(MethodNode mth, Map<Integer, BlockNode> blocksMap) {
for (BlockNode block : mth.getBasicBlocks()) {
for (InsnNode insn : block.getInstructions()) {
List<JumpInfo> jumps = insn.getAll(AType.JUMP);
for (JumpInfo jump : jumps) {
BlockNode srcBlock = getBlock(jump.getSrc(), blocksMap);
BlockNode thisBlock = getBlock(jump.getDest(), blocksMap);
connect(srcBlock, thisBlock);
}
connectExceptionHandlers(blocksMap, block, insn);
}
}
}
Aggregations