core: fix variable names propagation (#219)

This commit is contained in:
Skylot
2018-04-08 17:34:51 +03:00
parent 7a16814808
commit cb23b65797
10 changed files with 225 additions and 27 deletions
@@ -63,6 +63,21 @@ public class RegisterArg extends InsnArg implements Named {
return n.equals(((Named) arg).getName());
}
public void mergeName(InsnArg arg) {
if (arg instanceof Named) {
Named otherArg = (Named) arg;
String otherName = otherArg.getName();
String name = getName();
if (!Objects.equals(name, otherName)) {
if (name == null) {
setName(otherName);
} else if (otherName == null) {
otherArg.setName(name);
}
}
}
}
@Override
public void setType(ArgType type) {
if (sVar != null) {
@@ -78,6 +78,8 @@ public class DebugInfoParser {
addrChange(-1, 1, line);
setLine(addr, line);
boolean varsInfoFound = false;
int c = section.readByte() & 0xFF;
while (c != DBG_END_SEQUENCE) {
switch (c) {
@@ -98,6 +100,7 @@ public class DebugInfoParser {
int type = section.readUleb128() - 1;
LocalVar var = new LocalVar(dex, regNum, nameId, type, DexNode.NO_INDEX);
startVar(var, addr, line);
varsInfoFound = true;
break;
}
case DBG_START_LOCAL_EXTENDED: {
@@ -107,6 +110,7 @@ public class DebugInfoParser {
int sign = section.readUleb128() - 1;
LocalVar var = new LocalVar(dex, regNum, nameId, type, sign);
startVar(var, addr, line);
varsInfoFound = true;
break;
}
case DBG_RESTART_LOCAL: {
@@ -118,6 +122,7 @@ public class DebugInfoParser {
}
var.start(addr, line);
}
varsInfoFound = true;
break;
}
case DBG_END_LOCAL: {
@@ -127,6 +132,7 @@ public class DebugInfoParser {
var.end(addr, line);
setVar(var);
}
varsInfoFound = true;
break;
}
@@ -160,10 +166,12 @@ public class DebugInfoParser {
c = section.readByte() & 0xFF;
}
for (LocalVar var : locals) {
if (var != null && !var.isEnd()) {
var.end(mth.getCodeSize() - 1, line);
setVar(var);
if (varsInfoFound) {
for (LocalVar var : locals) {
if (var != null && !var.isEnd()) {
var.end(mth.getCodeSize() - 1, line);
setVar(var);
}
}
}
setSourceLines(addr, insnByOffset.length, line);
@@ -142,6 +142,7 @@ public class PrepareForCodeGen extends AbstractVisitor {
}
if (replace) {
insn.add(AFlag.ARITH_ONEARG);
insn.getResult().mergeName(arg);
}
}
}
@@ -22,7 +22,6 @@ import jadx.core.utils.exceptions.JadxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
@@ -8,6 +8,7 @@ import jadx.core.dex.instructions.PhiInsn;
import jadx.core.dex.instructions.args.InsnArg;
import jadx.core.dex.instructions.args.RegisterArg;
import jadx.core.dex.instructions.args.SSAVar;
import jadx.core.dex.instructions.args.VarName;
import jadx.core.dex.nodes.BlockNode;
import jadx.core.dex.nodes.InsnNode;
import jadx.core.dex.nodes.MethodNode;
@@ -141,14 +142,7 @@ public class SSATransform extends AbstractVisitor {
PhiListAttr phiList = enterBlock.get(AType.PHI_LIST);
if (phiList != null) {
for (PhiInsn phiInsn : phiList.getList()) {
int regNum = phiInsn.getResult().getRegNum();
SSAVar var = vars[regNum];
if (var == null) {
continue;
}
RegisterArg arg = phiInsn.bindArg(enterBlock);
var.use(arg);
var.setUsedInPhi(phiInsn);
bindPhiArg(vars, enterBlock, phiInsn);
}
}
}
@@ -183,14 +177,7 @@ public class SSATransform extends AbstractVisitor {
continue;
}
for (PhiInsn phiInsn : phiList.getList()) {
int regNum = phiInsn.getResult().getRegNum();
SSAVar var = vars[regNum];
if (var == null) {
continue;
}
RegisterArg arg = phiInsn.bindArg(block);
var.use(arg);
var.setUsedInPhi(phiInsn);
bindPhiArg(vars, block, phiInsn);
}
}
for (BlockNode domOn : block.getDominatesOn()) {
@@ -199,6 +186,17 @@ public class SSATransform extends AbstractVisitor {
System.arraycopy(inputVars, 0, vars, 0, vars.length);
}
private static void bindPhiArg(SSAVar[] vars, BlockNode block, PhiInsn phiInsn) {
int regNum = phiInsn.getResult().getRegNum();
SSAVar var = vars[regNum];
if (var == null) {
return;
}
RegisterArg arg = phiInsn.bindArg(block);
var.use(arg);
var.setUsedInPhi(phiInsn);
}
/**
* Fix last try/catch assign instruction
*/
@@ -1,17 +1,21 @@
package jadx.core.dex.visitors.typeinference;
import java.util.List;
import jadx.core.dex.attributes.AType;
import jadx.core.dex.attributes.nodes.PhiListAttr;
import jadx.core.dex.instructions.PhiInsn;
import jadx.core.dex.instructions.args.ArgType;
import jadx.core.dex.instructions.args.InsnArg;
import jadx.core.dex.instructions.args.RegisterArg;
import jadx.core.dex.instructions.args.SSAVar;
import jadx.core.dex.instructions.args.VarName;
import jadx.core.dex.nodes.BlockNode;
import jadx.core.dex.nodes.DexNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.visitors.AbstractVisitor;
import jadx.core.utils.exceptions.JadxException;
import java.util.List;
public class TypeInference extends AbstractVisitor {
@Override
@@ -19,6 +23,8 @@ public class TypeInference extends AbstractVisitor {
if (mth.isNoCode()) {
return;
}
fixPhiVarNames(mth);
DexNode dex = mth.dex();
for (SSAVar var : mth.getSVars()) {
// inference variable type
@@ -80,6 +86,32 @@ public class TypeInference extends AbstractVisitor {
}
}
private static void fixPhiVarNames(MethodNode mth) {
for (BlockNode block : mth.getBasicBlocks()) {
PhiListAttr phiList = block.get(AType.PHI_LIST);
if (phiList == null) {
continue;
}
for (PhiInsn phiInsn : phiList.getList()) {
RegisterArg resArg = phiInsn.getResult();
int argsCount = phiInsn.getArgsCount();
for (int i = 0; i < argsCount; i++) {
RegisterArg arg = phiInsn.getArg(i);
arg.mergeName(resArg);
}
VarName varName = resArg.getSVar().getVarName();
if (varName == null) {
varName = new VarName();
resArg.getSVar().setVarName(varName);
}
for (int i = 0; i < argsCount; i++) {
RegisterArg arg = phiInsn.getArg(i);
arg.getSVar().setVarName(varName);
}
}
}
}
private static String processVarName(SSAVar var) {
String name = var.getAssign().getName();
if (name != null) {