Merge pull request #19 from NeoSpb/fix3
core: fix processing of debug info (markup of local variables)
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user