提交 d1e0762c 编写于 作者: A Anton Dyachenko

core: fix processing of debug info (markup of local variables)

上级 010ae99c
...@@ -11,6 +11,9 @@ public class SSAVar { ...@@ -11,6 +11,9 @@ public class SSAVar {
private final int version; private final int version;
private VarName varName; private VarName varName;
private int startUseAddr;
private int endUseAddr;
private RegisterArg assign; private RegisterArg assign;
private final List<RegisterArg> useList = new ArrayList<RegisterArg>(2); private final List<RegisterArg> useList = new ArrayList<RegisterArg>(2);
private PhiInsn usedInPhi; private PhiInsn usedInPhi;
...@@ -25,12 +28,63 @@ public class SSAVar { ...@@ -25,12 +28,63 @@ public class SSAVar {
if (assign != null) { if (assign != null) {
assign.setSVar(this); assign.setSVar(this);
} }
startUseAddr = -1;
endUseAddr = -1;
} }
public int getRegNum() { public int getRegNum() {
return regNum; return regNum;
} }
public int getStartAddr() {
if (startUseAddr == -1) {
calcUsageAddrRange();
}
return startUseAddr;
}
public int getEndAddr() {
if (endUseAddr == -1) {
calcUsageAddrRange();
}
return endUseAddr;
}
private void calcUsageAddrRange() {
int start = Integer.MAX_VALUE;
int end = Integer.MIN_VALUE;
if (assign != null) {
if (assign.getParentInsn() != null) {
int insnAddr = assign.getParentInsn().getOffset();
if (insnAddr >= 0) {
start = Math.min(insnAddr, start);
end = Math.max(insnAddr, end);
}
}
}
for (RegisterArg arg : useList) {
if (arg.getParentInsn() != null) {
int insnAddr = arg.getParentInsn().getOffset();
if (insnAddr >= 0) {
start = Math.min(insnAddr, start);
end = Math.max(insnAddr, end);
}
}
}
if ((start != Integer.MAX_VALUE)
&& (end != Integer.MIN_VALUE)) {
startUseAddr = start;
endUseAddr = end;
}
}
public int getVersion() { public int getVersion() {
return version; return version;
} }
......
...@@ -52,6 +52,7 @@ public class MethodNode extends LineAttrNode implements ILoadable { ...@@ -52,6 +52,7 @@ public class MethodNode extends LineAttrNode implements ILoadable {
private final Method methodData; private final Method methodData;
private int regsCount; private int regsCount;
private InsnNode[] instructions; private InsnNode[] instructions;
private int codeSize;
private int debugInfoOffset; private int debugInfoOffset;
private boolean noCode; private boolean noCode;
...@@ -82,6 +83,7 @@ public class MethodNode extends LineAttrNode implements ILoadable { ...@@ -82,6 +83,7 @@ public class MethodNode extends LineAttrNode implements ILoadable {
try { try {
if (noCode) { if (noCode) {
regsCount = 0; regsCount = 0;
codeSize = 0;
initMethodTypes(); initMethodTypes();
return; return;
} }
...@@ -94,6 +96,7 @@ public class MethodNode extends LineAttrNode implements ILoadable { ...@@ -94,6 +96,7 @@ public class MethodNode extends LineAttrNode implements ILoadable {
InsnDecoder decoder = new InsnDecoder(this); InsnDecoder decoder = new InsnDecoder(this);
decoder.decodeInsns(mthCode); decoder.decodeInsns(mthCode);
instructions = decoder.process(); instructions = decoder.process();
codeSize = instructions.length;
initTryCatches(mthCode); initTryCatches(mthCode);
initJumps(); initJumps();
...@@ -350,6 +353,10 @@ public class MethodNode extends LineAttrNode implements ILoadable { ...@@ -350,6 +353,10 @@ public class MethodNode extends LineAttrNode implements ILoadable {
return noCode; return noCode;
} }
public int getCodeSize() {
return codeSize;
}
public InsnNode[] getInstructions() { public InsnNode[] getInstructions() {
return instructions; return instructions;
} }
......
...@@ -3,6 +3,7 @@ package jadx.core.dex.nodes.parser; ...@@ -3,6 +3,7 @@ package jadx.core.dex.nodes.parser;
import jadx.core.dex.attributes.nodes.SourceFileAttr; import jadx.core.dex.attributes.nodes.SourceFileAttr;
import jadx.core.dex.instructions.args.InsnArg; import jadx.core.dex.instructions.args.InsnArg;
import jadx.core.dex.instructions.args.RegisterArg; import jadx.core.dex.instructions.args.RegisterArg;
import jadx.core.dex.instructions.args.SSAVar;
import jadx.core.dex.nodes.DexNode; import jadx.core.dex.nodes.DexNode;
import jadx.core.dex.nodes.InsnNode; import jadx.core.dex.nodes.InsnNode;
import jadx.core.dex.nodes.MethodNode; import jadx.core.dex.nodes.MethodNode;
...@@ -112,8 +113,9 @@ public class DebugInfoParser { ...@@ -112,8 +113,9 @@ public class DebugInfoParser {
int regNum = section.readUleb128(); int regNum = section.readUleb128();
LocalVar var = locals[regNum]; LocalVar var = locals[regNum];
if (var != null) { if (var != null) {
var.end(addr, line); if (var.end(addr, line)) {
setVar(var); setVar(var);
}
var.start(addr, line); var.start(addr, line);
} }
break; break;
...@@ -160,7 +162,7 @@ public class DebugInfoParser { ...@@ -160,7 +162,7 @@ public class DebugInfoParser {
for (LocalVar var : locals) { for (LocalVar var : locals) {
if (var != null && !var.isEnd()) { if (var != null && !var.isEnd()) {
var.end(addr, line); var.end(mth.getCodeSize()-1, line);
setVar(var); setVar(var);
} }
} }
...@@ -236,7 +238,27 @@ public class DebugInfoParser { ...@@ -236,7 +238,27 @@ public class DebugInfoParser {
if (arg != null && arg.isRegister()) { if (arg != null && arg.isRegister()) {
RegisterArg reg = (RegisterArg) arg; RegisterArg reg = (RegisterArg) arg;
if (var.getRegNum() == reg.getRegNum()) { if (var.getRegNum() == reg.getRegNum()) {
reg.mergeDebugInfo(var.getType(), var.getName()); SSAVar ssaVar = reg.getSVar();
boolean mergeRequired = false;
if (ssaVar != null) {
int ssaEnd = ssaVar.getEndAddr();
int ssaStart = ssaVar.getStartAddr();
int localStart = var.getStartAddr();
int localEnd = var.getEndAddr();
boolean isIntersected = !((localEnd < ssaStart) || (ssaEnd < localStart));
if (isIntersected && (ssaEnd <= localEnd)) {
mergeRequired = true;
}
} else {
mergeRequired = true;
}
if (mergeRequired) {
reg.mergeDebugInfo(var.getType(), var.getName());
}
} }
} }
} }
......
...@@ -69,9 +69,20 @@ final class LocalVar { ...@@ -69,9 +69,20 @@ final class LocalVar {
this.startAddr = addr; this.startAddr = addr;
} }
public void end(int addr, int line) { /**
this.isEnd = true; * Sets end address of local variable
this.endAddr = addr; * @param addr address
* @param line source line
* @return <b>true</b> if local variable was active, else <b>false</b>
*/
public boolean end(int addr, int line) {
if (!isEnd) {
this.isEnd = true;
this.endAddr = addr;
return true;
}
return false;
} }
public int getRegNum() { public int getRegNum() {
......
...@@ -80,6 +80,7 @@ public class SSATransform extends AbstractVisitor { ...@@ -80,6 +80,7 @@ public class SSATransform extends AbstractVisitor {
} }
PhiInsn phiInsn = new PhiInsn(regNum, block.getPredecessors().size()); PhiInsn phiInsn = new PhiInsn(regNum, block.getPredecessors().size());
phiList.getList().add(phiInsn); phiList.getList().add(phiInsn);
phiInsn.setOffset(block.getStartOffset());
block.getInstructions().add(0, phiInsn); block.getInstructions().add(0, phiInsn);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册