use of jadx.core.dex.trycatch.ExcHandlerAttr in project jadx by skylot.
the class RegionMaker method processExcHandler.
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);
}
}
use of jadx.core.dex.trycatch.ExcHandlerAttr in project jadx by skylot.
the class BlockExceptionHandler method markExceptionHandlers.
/**
* Set exception handler attribute for whole block
*/
private static void markExceptionHandlers(BlockNode block) {
if (block.getInstructions().isEmpty()) {
return;
}
InsnNode me = block.getInstructions().get(0);
ExcHandlerAttr handlerAttr = me.get(AType.EXC_HANDLER);
if (handlerAttr == null || me.getType() != InsnType.MOVE_EXCEPTION) {
return;
}
ExceptionHandler excHandler = handlerAttr.getHandler();
block.addAttr(handlerAttr);
// set correct type for 'move-exception' operation
ArgType type = excHandler.isCatchAll() ? ArgType.THROWABLE : excHandler.getCatchType().getType();
RegisterArg resArg = me.getResult();
resArg = InsnArg.reg(resArg.getRegNum(), type);
me.setResult(resArg);
me.add(AFlag.DONT_INLINE);
excHandler.setArg(resArg);
}
use of jadx.core.dex.trycatch.ExcHandlerAttr in project jadx by skylot.
the class ModVisitor method processMoveException.
private static void processMoveException(MethodNode mth, BlockNode block, InsnNode insn, InstructionRemover remover) {
ExcHandlerAttr excHandlerAttr = block.get(AType.EXC_HANDLER);
if (excHandlerAttr == null) {
return;
}
ExceptionHandler excHandler = excHandlerAttr.getHandler();
// result arg used both in this insn and exception handler,
RegisterArg resArg = insn.getResult();
ArgType type = excHandler.isCatchAll() ? ArgType.THROWABLE : excHandler.getCatchType().getType();
String name = excHandler.isCatchAll() ? "th" : "e";
if (resArg.getName() == null) {
resArg.setName(name);
}
SSAVar sVar = insn.getResult().getSVar();
if (sVar.getUseCount() == 0) {
excHandler.setArg(new NamedArg(name, type));
remover.add(insn);
} else if (sVar.isUsedInPhi()) {
// exception var moved to external variable => replace with 'move' insn
InsnNode moveInsn = new InsnNode(InsnType.MOVE, 1);
moveInsn.setResult(insn.getResult());
NamedArg namedArg = new NamedArg(name, type);
moveInsn.addArg(namedArg);
excHandler.setArg(namedArg);
replaceInsn(block, 0, moveInsn);
}
}
use of jadx.core.dex.trycatch.ExcHandlerAttr in project jadx by skylot.
the class MethodNode method initTryCatches.
private void initTryCatches(Code mthCode) {
InsnNode[] insnByOffset = instructions;
CatchHandler[] catchBlocks = mthCode.getCatchHandlers();
Try[] tries = mthCode.getTries();
if (catchBlocks.length == 0 && tries.length == 0) {
return;
}
int hc = 0;
Set<Integer> addrs = new HashSet<Integer>();
List<TryCatchBlock> catches = new ArrayList<TryCatchBlock>(catchBlocks.length);
for (CatchHandler handler : catchBlocks) {
TryCatchBlock tcBlock = new TryCatchBlock();
catches.add(tcBlock);
for (int i = 0; i < handler.getAddresses().length; i++) {
int addr = handler.getAddresses()[i];
ClassInfo type = ClassInfo.fromDex(parentClass.dex(), handler.getTypeIndexes()[i]);
tcBlock.addHandler(this, addr, type);
addrs.add(addr);
hc++;
}
int addr = handler.getCatchAllAddress();
if (addr >= 0) {
tcBlock.addHandler(this, addr, null);
addrs.add(addr);
hc++;
}
}
if (hc > 0 && hc != addrs.size()) {
// each handler must be only in one try/catch block
for (TryCatchBlock ct1 : catches) {
for (TryCatchBlock ct2 : catches) {
if (ct1 != ct2 && ct2.containsAllHandlers(ct1)) {
for (ExceptionHandler h : ct1.getHandlers()) {
ct2.removeHandler(this, h);
h.setTryBlock(ct1);
}
}
}
}
}
// attach EXC_HANDLER attributes to instructions
addrs.clear();
for (TryCatchBlock ct : catches) {
for (ExceptionHandler eh : ct.getHandlers()) {
int addr = eh.getHandleOffset();
ExcHandlerAttr ehAttr = new ExcHandlerAttr(ct, eh);
insnByOffset[addr].addAttr(ehAttr);
}
}
// attach TRY_ENTER, TRY_LEAVE attributes to instructions
for (Try aTry : tries) {
int catchNum = aTry.getCatchHandlerIndex();
TryCatchBlock catchBlock = catches.get(catchNum);
int offset = aTry.getStartAddress();
int end = offset + aTry.getInstructionCount() - 1;
InsnNode insn = insnByOffset[offset];
insn.add(AFlag.TRY_ENTER);
while (offset <= end && offset >= 0) {
insn = insnByOffset[offset];
catchBlock.addInsn(insn);
offset = InsnDecoder.getNextInsnOffset(insnByOffset, offset);
}
if (insnByOffset[end] != null) {
insnByOffset[end].add(AFlag.TRY_LEAVE);
} else {
insn.add(AFlag.TRY_LEAVE);
}
}
}
use of jadx.core.dex.trycatch.ExcHandlerAttr in project jadx by skylot.
the class BlockExceptionHandler method processExceptionHandlers.
private static void processExceptionHandlers(MethodNode mth, BlockNode block) {
ExcHandlerAttr handlerAttr = block.get(AType.EXC_HANDLER);
if (handlerAttr == null) {
return;
}
ExceptionHandler excHandler = handlerAttr.getHandler();
excHandler.addBlock(block);
for (BlockNode node : BlockUtils.collectBlocksDominatedBy(block, block)) {
excHandler.addBlock(node);
}
for (BlockNode excBlock : excHandler.getBlocks()) {
// remove 'monitor-exit' from exception handler blocks
InstructionRemover remover = new InstructionRemover(mth, excBlock);
for (InsnNode insn : excBlock.getInstructions()) {
if (insn.getType() == InsnType.MONITOR_ENTER) {
break;
}
if (insn.getType() == InsnType.MONITOR_EXIT) {
remover.add(insn);
}
}
remover.perform();
// if 'throw' in exception handler block have 'catch' - merge these catch blocks
for (InsnNode insn : excBlock.getInstructions()) {
CatchAttr catchAttr = insn.get(AType.CATCH_BLOCK);
if (catchAttr == null) {
continue;
}
if (insn.getType() == InsnType.THROW || onlyAllHandler(catchAttr.getTryBlock())) {
TryCatchBlock handlerBlock = handlerAttr.getTryBlock();
TryCatchBlock catchBlock = catchAttr.getTryBlock();
handlerBlock.merge(mth, catchBlock);
}
}
}
}
Aggregations