Commit c363bea5 authored by Skylot's avatar Skylot

Set debug info for unused variables

parent 3fcbca94
...@@ -4,6 +4,7 @@ import jadx.dex.instructions.args.ArgType; ...@@ -4,6 +4,7 @@ import jadx.dex.instructions.args.ArgType;
import jadx.dex.instructions.args.RegisterArg; import jadx.dex.instructions.args.RegisterArg;
import jadx.dex.instructions.args.TypedVar; import jadx.dex.instructions.args.TypedVar;
import jadx.dex.nodes.DexNode; import jadx.dex.nodes.DexNode;
import jadx.utils.InsnUtils;
public class LocalVarInfo extends RegisterArg { public class LocalVarInfo extends RegisterArg {
...@@ -21,9 +22,9 @@ public class LocalVarInfo extends RegisterArg { ...@@ -21,9 +22,9 @@ public class LocalVarInfo extends RegisterArg {
init(name, type, sign); init(name, type, sign);
} }
public LocalVarInfo(DexNode dex, int rn, String name, ArgType type, String sign) { public LocalVarInfo(DexNode dex, RegisterArg arg) {
super(rn); super(arg.getRegNum());
init(name, type, sign); init(arg.getTypedVar().getName(), arg.getType(), null);
} }
private void init(String name, ArgType type, String sign) { private void init(String name, ArgType type, String sign) {
...@@ -59,6 +60,8 @@ public class LocalVarInfo extends RegisterArg { ...@@ -59,6 +60,8 @@ public class LocalVarInfo extends RegisterArg {
@Override @Override
public String toString() { public String toString() {
return super.toString() + " " + (isEnd ? "end" : "active"); return super.toString() + " " + (isEnd
? "end: " + InsnUtils.formatOffset(startAddr) + "-" + InsnUtils.formatOffset(endAddr)
: "active: " + InsnUtils.formatOffset(startAddr));
} }
} }
...@@ -33,13 +33,21 @@ public class DebugInfoParser { ...@@ -33,13 +33,21 @@ public class DebugInfoParser {
private final Section section; private final Section section;
private final DexNode dex; private final DexNode dex;
public DebugInfoParser(MethodNode mth, int debugOffset) { private final LocalVarInfo[] locals;
private final InsnArg[] activeRegisters;
private final InsnNode[] insnByOffset;
public DebugInfoParser(MethodNode mth, int debugOffset, InsnNode[] insnByOffset) {
this.mth = mth; this.mth = mth;
this.dex = mth.dex(); this.dex = mth.dex();
this.section = dex.openSection(debugOffset); this.section = dex.openSection(debugOffset);
this.locals = new LocalVarInfo[mth.getRegsCount()];
this.activeRegisters = new InsnArg[mth.getRegsCount()];
this.insnByOffset = insnByOffset;
} }
public void process(InsnNode[] insnByOffset) throws DecodeException { public void process() throws DecodeException {
int addr = 0; int addr = 0;
int line; int line;
// String source_file; // String source_file;
...@@ -57,28 +65,33 @@ public class DebugInfoParser { ...@@ -57,28 +65,33 @@ public class DebugInfoParser {
} }
} }
LocalVarInfo[] locals = new LocalVarInfo[mth.getRegsCount()];
for (RegisterArg arg : mthArgs) { for (RegisterArg arg : mthArgs) {
locals[arg.getRegNum()] = new LocalVarInfo(dex, arg.getRegNum(), int rn = arg.getRegNum();
arg.getTypedVar().getName(), arg.getType(), null); locals[rn] = new LocalVarInfo(dex, arg);
activeRegisters[rn] = arg;
} }
addrChange(-1, 1); // process '0' instruction
int c = section.readByte() & 0xFF; int c = section.readByte() & 0xFF;
while (c != DBG_END_SEQUENCE) { while (c != DBG_END_SEQUENCE) {
switch (c) { switch (c) {
case DBG_ADVANCE_PC: case DBG_ADVANCE_PC: {
addr += section.readUleb128(); int addrInc = section.readUleb128();
addr = addrChange(addr, addrInc);
break; break;
case DBG_ADVANCE_LINE: }
case DBG_ADVANCE_LINE: {
line += section.readSleb128(); line += section.readSleb128();
break; break;
}
case DBG_START_LOCAL: { case DBG_START_LOCAL: {
int regNum = section.readUleb128(); int regNum = section.readUleb128();
int nameId = section.readUleb128() - 1; int nameId = section.readUleb128() - 1;
int type = section.readUleb128() - 1; int type = section.readUleb128() - 1;
LocalVarInfo var = new LocalVarInfo(dex, regNum, nameId, type, DexNode.NO_INDEX); LocalVarInfo var = new LocalVarInfo(dex, regNum, nameId, type, DexNode.NO_INDEX);
startVar(var, locals, insnByOffset, addr, line); startVar(var, addr, line);
break; break;
} }
case DBG_START_LOCAL_EXTENDED: { case DBG_START_LOCAL_EXTENDED: {
...@@ -87,7 +100,7 @@ public class DebugInfoParser { ...@@ -87,7 +100,7 @@ public class DebugInfoParser {
int type = section.readUleb128() - 1; int type = section.readUleb128() - 1;
int sign = section.readUleb128() - 1; int sign = section.readUleb128() - 1;
LocalVarInfo var = new LocalVarInfo(dex, regNum, nameId, type, sign); LocalVarInfo var = new LocalVarInfo(dex, regNum, nameId, type, sign);
startVar(var, locals, insnByOffset, addr, line); startVar(var, addr, line);
break; break;
} }
case DBG_RESTART_LOCAL: { case DBG_RESTART_LOCAL: {
...@@ -95,7 +108,7 @@ public class DebugInfoParser { ...@@ -95,7 +108,7 @@ public class DebugInfoParser {
LocalVarInfo var = locals[regNum]; LocalVarInfo var = locals[regNum];
if (var != null) { if (var != null) {
var.end(addr, line); var.end(addr, line);
setVar(var, insnByOffset); setVar(var);
var.start(addr, line); var.start(addr, line);
} }
break; break;
...@@ -105,7 +118,7 @@ public class DebugInfoParser { ...@@ -105,7 +118,7 @@ public class DebugInfoParser {
LocalVarInfo var = locals[regNum]; LocalVarInfo var = locals[regNum];
if (var != null) { if (var != null) {
var.end(addr, line); var.end(addr, line);
setVar(var, insnByOffset); setVar(var);
} }
break; break;
} }
...@@ -120,15 +133,17 @@ public class DebugInfoParser { ...@@ -120,15 +133,17 @@ public class DebugInfoParser {
// source_file = dex.getString(idx); // source_file = dex.getString(idx);
break; break;
default: default: {
if (c >= DBG_FIRST_SPECIAL) { if (c >= DBG_FIRST_SPECIAL) {
int adjusted_opcode = c - DBG_FIRST_SPECIAL; int adjusted_opcode = c - DBG_FIRST_SPECIAL;
line += DBG_LINE_BASE + (adjusted_opcode % DBG_LINE_RANGE); line += DBG_LINE_BASE + (adjusted_opcode % DBG_LINE_RANGE);
addr += (adjusted_opcode / DBG_LINE_RANGE); int addrInc = (adjusted_opcode / DBG_LINE_RANGE);
addr = addrChange(addr, addrInc);
} else { } else {
throw new DecodeException("Unknown debug insn code: " + c); throw new DecodeException("Unknown debug insn code: " + c);
} }
break; break;
}
} }
c = section.readByte() & 0xFF; c = section.readByte() & 0xFF;
...@@ -137,36 +152,54 @@ public class DebugInfoParser { ...@@ -137,36 +152,54 @@ public class DebugInfoParser {
for (LocalVarInfo var : locals) { for (LocalVarInfo var : locals) {
if (var != null && !var.isEnd()) { if (var != null && !var.isEnd()) {
var.end(addr, line); var.end(addr, line);
setVar(var, insnByOffset); setVar(var);
} }
} }
} }
private void startVar(LocalVarInfo var, LocalVarInfo[] locals, InsnNode[] insnByOffset, int addr, int line) { private int addrChange(int addr, int addrInc) {
int newAddr = addr + addrInc;
for (int i = addr + 1; i <= newAddr; i++) {
InsnNode insn = insnByOffset[i];
if (insn == null)
continue;
for (InsnArg arg : insn.getArguments())
if (arg.isRegister()) {
activeRegisters[arg.getRegNum()] = arg;
}
RegisterArg res = insn.getResult();
if (res != null)
activeRegisters[res.getRegNum()] = res;
}
return newAddr;
}
private void startVar(LocalVarInfo var, int addr, int line) {
int regNum = var.getRegNum(); int regNum = var.getRegNum();
LocalVarInfo prev = locals[regNum]; LocalVarInfo prev = locals[regNum];
if (prev != null && !prev.isEnd()) { if (prev != null && !prev.isEnd()) {
prev.end(addr, line); prev.end(addr, line);
setVar(prev, insnByOffset); setVar(prev);
} }
var.start(addr, line); var.start(addr, line);
locals[regNum] = var; locals[regNum] = var;
} }
private void setVar(LocalVarInfo var, InsnNode[] insnByOffset) { private void setVar(LocalVarInfo var) {
int start = var.getStartAddr(); int start = var.getStartAddr();
int end = var.getEndAddr(); int end = var.getEndAddr();
for (int i = start; i <= end; i++) { for (int i = start; i <= end; i++) {
InsnNode insn = insnByOffset[i]; InsnNode insn = insnByOffset[i];
fillLocals(insn, var); if (insn != null)
fillLocals(insn, var);
} }
merge(activeRegisters[var.getRegNum()], var);
} }
private void fillLocals(InsnNode insn, LocalVarInfo var) { private static void fillLocals(InsnNode insn, LocalVarInfo var) {
if (insn == null)
return;
if (insn.getResult() != null) if (insn.getResult() != null)
merge(insn.getResult(), var); merge(insn.getResult(), var);
...@@ -174,10 +207,9 @@ public class DebugInfoParser { ...@@ -174,10 +207,9 @@ public class DebugInfoParser {
merge(arg, var); merge(arg, var);
} }
private void merge(InsnArg arg, LocalVarInfo var) { private static void merge(InsnArg arg, LocalVarInfo var) {
if (arg.isRegister()) { if (arg != null && arg.isRegister()) {
int rn = ((RegisterArg) arg).getRegNum(); if (var.getRegNum() == arg.getRegNum())
if (var.getRegNum() == rn)
arg.setTypedVar(var.getTypedVar()); arg.setTypedVar(var.getTypedVar());
} }
} }
......
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