Commit 8f201f1f authored by skylot's avatar skylot

Merge pull request #19 from NeoSpb/fix3

core: fix processing of debug info (markup of local variables)
parents 010ae99c d1e0762c
......@@ -11,6 +11,9 @@ public class SSAVar {
private final int version;
private VarName varName;
private int startUseAddr;
private int endUseAddr;
private RegisterArg assign;
private final List<RegisterArg> useList = new ArrayList<RegisterArg>(2);
private PhiInsn usedInPhi;
......@@ -25,12 +28,63 @@ public class SSAVar {
if (assign != null) {
assign.setSVar(this);
}
startUseAddr = -1;
endUseAddr = -1;
}
public int getRegNum() {
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() {
return version;
}
......
......@@ -52,6 +52,7 @@ public class MethodNode extends LineAttrNode implements ILoadable {
private final Method methodData;
private int regsCount;
private InsnNode[] instructions;
private int codeSize;
private int debugInfoOffset;
private boolean noCode;
......@@ -82,6 +83,7 @@ public class MethodNode extends LineAttrNode implements ILoadable {
try {
if (noCode) {
regsCount = 0;
codeSize = 0;
initMethodTypes();
return;
}
......@@ -94,6 +96,7 @@ public class MethodNode extends LineAttrNode implements ILoadable {
InsnDecoder decoder = new InsnDecoder(this);
decoder.decodeInsns(mthCode);
instructions = decoder.process();
codeSize = instructions.length;
initTryCatches(mthCode);
initJumps();
......@@ -350,6 +353,10 @@ public class MethodNode extends LineAttrNode implements ILoadable {
return noCode;
}
public int getCodeSize() {
return codeSize;
}
public InsnNode[] getInstructions() {
return instructions;
}
......
......@@ -3,6 +3,7 @@ package jadx.core.dex.nodes.parser;
import jadx.core.dex.attributes.nodes.SourceFileAttr;
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.nodes.DexNode;
import jadx.core.dex.nodes.InsnNode;
import jadx.core.dex.nodes.MethodNode;
......@@ -112,8 +113,9 @@ public class DebugInfoParser {
int regNum = section.readUleb128();
LocalVar var = locals[regNum];
if (var != null) {
var.end(addr, line);
setVar(var);
if (var.end(addr, line)) {
setVar(var);
}
var.start(addr, line);
}
break;
......@@ -160,7 +162,7 @@ public class DebugInfoParser {
for (LocalVar var : locals) {
if (var != null && !var.isEnd()) {
var.end(addr, line);
var.end(mth.getCodeSize()-1, line);
setVar(var);
}
}
......@@ -236,7 +238,27 @@ public class DebugInfoParser {
if (arg != null && arg.isRegister()) {
RegisterArg reg = (RegisterArg) arg;
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 {
this.startAddr = addr;
}
public void end(int addr, int line) {
this.isEnd = true;
this.endAddr = addr;
/**
* Sets end address of local variable
* @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() {
......
......@@ -80,6 +80,7 @@ public class SSATransform extends AbstractVisitor {
}
PhiInsn phiInsn = new PhiInsn(regNum, block.getPredecessors().size());
phiList.getList().add(phiInsn);
phiInsn.setOffset(block.getStartOffset());
block.getInstructions().add(0, phiInsn);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment