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 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 RegionGen method makeCatchBlock.
private void makeCatchBlock(ICodeWriter code, ExceptionHandler handler) throws CodegenException {
IContainer region = handler.getHandlerRegion();
if (region == null) {
return;
}
code.startLine("} catch (");
if (handler.isCatchAll()) {
useClass(code, ArgType.THROWABLE);
} else {
Iterator<ClassInfo> it = handler.getCatchTypes().iterator();
if (it.hasNext()) {
useClass(code, it.next());
}
while (it.hasNext()) {
code.add(" | ");
useClass(code, it.next());
}
}
code.add(' ');
InsnArg arg = handler.getArg();
if (arg == null) {
// throwing exception is too late at this point
code.add("unknown");
} else if (arg instanceof RegisterArg) {
CodeVar codeVar = ((RegisterArg) arg).getSVar().getCodeVar();
if (code.isMetadataSupported()) {
code.attachDefinition(VarDeclareRef.get(mth, codeVar));
}
code.add(mgen.getNameGen().assignArg(codeVar));
} else if (arg instanceof NamedArg) {
code.add(mgen.getNameGen().assignNamedArg((NamedArg) arg));
} else {
throw new JadxRuntimeException("Unexpected arg type in catch block: " + arg + ", class: " + arg.getClass().getSimpleName());
}
code.add(") {");
InsnCodeOffset.attach(code, handler.getHandlerOffset());
CodeGenUtils.addCodeComments(code, mth, handler.getHandlerBlock());
makeRegionIndent(code, region);
}
use of jadx.core.utils.exceptions.JadxRuntimeException in project jadx by skylot.
the class JsonCodeGen method fillMthCode.
private List<JsonCodeLine> fillMthCode(MethodNode mth, MethodGen mthGen) {
if (mth.isNoCode()) {
return Collections.emptyList();
}
ICodeWriter cw = mth.root().makeCodeWriter();
try {
mthGen.addInstructions(cw);
} catch (Exception e) {
throw new JadxRuntimeException("Method generation error", e);
}
ICodeInfo code = cw.finish();
String codeStr = code.getCodeStr();
if (codeStr.isEmpty()) {
return Collections.emptyList();
}
String[] lines = codeStr.split(ICodeWriter.NL);
Map<Integer, Integer> lineMapping = code.getLineMapping();
Map<CodePosition, Object> annotations = code.getAnnotations();
long mthCodeOffset = mth.getMethodCodeOffset() + 16;
int linesCount = lines.length;
List<JsonCodeLine> codeLines = new ArrayList<>(linesCount);
for (int i = 0; i < linesCount; i++) {
String codeLine = lines[i];
int line = i + 2;
JsonCodeLine jsonCodeLine = new JsonCodeLine();
jsonCodeLine.setCode(codeLine);
jsonCodeLine.setSourceLine(lineMapping.get(line));
Object obj = annotations.get(new CodePosition(line));
if (obj instanceof InsnCodeOffset) {
long offset = ((InsnCodeOffset) obj).getOffset();
jsonCodeLine.setOffset("0x" + Long.toHexString(mthCodeOffset + offset * 2));
}
codeLines.add(jsonCodeLine);
}
return codeLines;
}
use of jadx.core.utils.exceptions.JadxRuntimeException in project jadx by skylot.
the class AnnotationGen method encodeValue.
// TODO: refactor this boilerplate code
public void encodeValue(RootNode root, ICodeWriter code, EncodedValue encodedValue) {
if (encodedValue == null) {
code.add("null");
return;
}
Object value = encodedValue.getValue();
switch(encodedValue.getType()) {
case ENCODED_NULL:
code.add("null");
break;
case ENCODED_BOOLEAN:
code.add(Boolean.TRUE.equals(value) ? "true" : "false");
break;
case ENCODED_BYTE:
code.add(TypeGen.formatByte((Byte) value, false));
break;
case ENCODED_SHORT:
code.add(TypeGen.formatShort((Short) value, false));
break;
case ENCODED_CHAR:
code.add(getStringUtils().unescapeChar((Character) value));
break;
case ENCODED_INT:
code.add(TypeGen.formatInteger((Integer) value, false));
break;
case ENCODED_LONG:
code.add(TypeGen.formatLong((Long) value, false));
break;
case ENCODED_FLOAT:
code.add(TypeGen.formatFloat((Float) value));
break;
case ENCODED_DOUBLE:
code.add(TypeGen.formatDouble((Double) value));
break;
case ENCODED_STRING:
code.add(getStringUtils().unescapeString((String) value));
break;
case ENCODED_TYPE:
classGen.useType(code, ArgType.parse((String) value));
code.add(".class");
break;
case ENCODED_ENUM:
case ENCODED_FIELD:
// must be a static field
if (value instanceof IFieldRef) {
FieldInfo fieldInfo = FieldInfo.fromRef(root, (IFieldRef) value);
InsnGen.makeStaticFieldAccess(code, fieldInfo, classGen);
} else if (value instanceof FieldInfo) {
InsnGen.makeStaticFieldAccess(code, (FieldInfo) value, classGen);
} else {
throw new JadxRuntimeException("Unexpected field type class: " + value.getClass());
}
break;
case ENCODED_METHOD:
// TODO
break;
case ENCODED_ARRAY:
code.add('{');
Iterator<?> it = ((Iterable<?>) value).iterator();
while (it.hasNext()) {
EncodedValue v = (EncodedValue) it.next();
encodeValue(cls.root(), code, v);
if (it.hasNext()) {
code.add(", ");
}
}
code.add('}');
break;
case ENCODED_ANNOTATION:
formatAnnotation(code, (IAnnotation) value);
break;
default:
throw new JadxRuntimeException("Can't decode value: " + encodedValue.getType() + " (" + encodedValue + ')');
}
}
Aggregations