use of org.jf.dexlib2.iface.debug.LineNumber in project smali by JesusFreke.
the class FixOffsetsTest method testFixOffsets.
@Test
public void testFixOffsets() {
MethodImplementationBuilder builder = new MethodImplementationBuilder(1);
Label firstGotoTarget = builder.getLabel("firstGotoTarget");
builder.addInstruction(new BuilderInstruction10t(Opcode.GOTO, firstGotoTarget));
builder.addLineNumber(1);
for (int i = 0; i < 250; i++) {
builder.addInstruction(new BuilderInstruction10x(Opcode.NOP));
}
builder.addLabel("tryStart");
builder.addLineNumber(2);
for (int i = 0; i < 250; i++) {
builder.addInstruction(new BuilderInstruction10x(Opcode.NOP));
}
builder.addLineNumber(3);
Label secondGotoTarget = builder.getLabel("secondGotoTarget");
builder.addInstruction(new BuilderInstruction10t(Opcode.GOTO, secondGotoTarget));
builder.addLineNumber(4);
builder.addLabel("handler");
for (int i = 0; i < 500; i++) {
builder.addInstruction(new BuilderInstruction10x(Opcode.NOP));
}
builder.addLineNumber(5);
builder.addLabel("tryEnd");
builder.addLabel("firstGotoTarget");
builder.addLabel("secondGotoTarget");
builder.addInstruction(new BuilderInstruction10x(Opcode.RETURN_VOID));
Label tryStart = builder.getLabel("tryStart");
Label tryEnd = builder.getLabel("tryEnd");
Label handler = builder.getLabel("handler");
builder.addCatch(tryStart, tryEnd, handler);
MethodImplementation impl = builder.getMethodImplementation();
List<? extends Instruction> instructions = Lists.newArrayList(impl.getInstructions());
Assert.assertEquals(1003, instructions.size());
Assert.assertEquals(Opcode.GOTO_16, instructions.get(0).getOpcode());
Assert.assertEquals(1004, ((OffsetInstruction) instructions.get(0)).getCodeOffset());
Assert.assertEquals(Opcode.GOTO_16, instructions.get(501).getOpcode());
Assert.assertEquals(502, ((OffsetInstruction) instructions.get(501)).getCodeOffset());
List<? extends TryBlock<? extends ExceptionHandler>> exceptionHandlers = impl.getTryBlocks();
Assert.assertEquals(1, exceptionHandlers.size());
Assert.assertEquals(252, exceptionHandlers.get(0).getStartCodeAddress());
Assert.assertEquals(752, exceptionHandlers.get(0).getCodeUnitCount());
Assert.assertEquals(1, exceptionHandlers.get(0).getExceptionHandlers().size());
ExceptionHandler exceptionHandler = exceptionHandlers.get(0).getExceptionHandlers().get(0);
Assert.assertEquals(504, exceptionHandler.getHandlerCodeAddress());
List<DebugItem> debugItems = Lists.newArrayList(impl.getDebugItems());
Assert.assertEquals(5, debugItems.size());
Assert.assertEquals(1, ((LineNumber) debugItems.get(0)).getLineNumber());
Assert.assertEquals(2, debugItems.get(0).getCodeAddress());
Assert.assertEquals(2, ((LineNumber) debugItems.get(1)).getLineNumber());
Assert.assertEquals(252, debugItems.get(1).getCodeAddress());
Assert.assertEquals(3, ((LineNumber) debugItems.get(2)).getLineNumber());
Assert.assertEquals(502, debugItems.get(2).getCodeAddress());
Assert.assertEquals(4, ((LineNumber) debugItems.get(3)).getLineNumber());
Assert.assertEquals(504, debugItems.get(3).getCodeAddress());
Assert.assertEquals(5, ((LineNumber) debugItems.get(4)).getLineNumber());
Assert.assertEquals(1004, debugItems.get(4).getCodeAddress());
}
use of org.jf.dexlib2.iface.debug.LineNumber in project smali by JesusFreke.
the class DebugInfoItem method makeAnnotator.
@Nonnull
public static SectionAnnotator makeAnnotator(@Nonnull DexAnnotator annotator, @Nonnull MapItem mapItem) {
return new SectionAnnotator(annotator, mapItem) {
@Nonnull
@Override
public String getItemName() {
return "debug_info_item";
}
@Override
public void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
DexReader reader = dexFile.readerAt(out.getCursor());
int lineStart = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "line_start = %d", lineStart);
int parametersSize = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "parameters_size = %d", parametersSize);
if (parametersSize > 0) {
out.annotate(0, "parameters:");
out.indent();
for (int i = 0; i < parametersSize; i++) {
int paramaterIndex = reader.readSmallUleb128() - 1;
out.annotateTo(reader.getOffset(), "%s", StringIdItem.getOptionalReferenceAnnotation(dexFile, paramaterIndex, true));
}
out.deindent();
}
out.annotate(0, "debug opcodes:");
out.indent();
int codeAddress = 0;
int lineNumber = lineStart;
loop: while (true) {
int opcode = reader.readUbyte();
switch(opcode) {
case DebugItemType.END_SEQUENCE:
{
out.annotateTo(reader.getOffset(), "DBG_END_SEQUENCE");
break loop;
}
case DebugItemType.ADVANCE_PC:
{
out.annotateTo(reader.getOffset(), "DBG_ADVANCE_PC");
out.indent();
int addressDiff = reader.readSmallUleb128();
codeAddress += addressDiff;
out.annotateTo(reader.getOffset(), "addr_diff = +0x%x: 0x%x", addressDiff, codeAddress);
out.deindent();
break;
}
case DebugItemType.ADVANCE_LINE:
{
out.annotateTo(reader.getOffset(), "DBG_ADVANCE_LINE");
out.indent();
int lineDiff = reader.readSleb128();
lineNumber += lineDiff;
out.annotateTo(reader.getOffset(), "line_diff = +%d: %d", Math.abs(lineDiff), lineNumber);
out.deindent();
break;
}
case DebugItemType.START_LOCAL:
{
out.annotateTo(reader.getOffset(), "DBG_START_LOCAL");
out.indent();
int registerNum = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "register_num = v%d", registerNum);
int nameIndex = reader.readSmallUleb128() - 1;
out.annotateTo(reader.getOffset(), "name_idx = %s", StringIdItem.getOptionalReferenceAnnotation(dexFile, nameIndex, true));
int typeIndex = reader.readSmallUleb128() - 1;
out.annotateTo(reader.getOffset(), "type_idx = %s", TypeIdItem.getOptionalReferenceAnnotation(dexFile, typeIndex));
out.deindent();
break;
}
case DebugItemType.START_LOCAL_EXTENDED:
{
out.annotateTo(reader.getOffset(), "DBG_START_LOCAL_EXTENDED");
out.indent();
int registerNum = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "register_num = v%d", registerNum);
int nameIndex = reader.readSmallUleb128() - 1;
out.annotateTo(reader.getOffset(), "name_idx = %s", StringIdItem.getOptionalReferenceAnnotation(dexFile, nameIndex, true));
int typeIndex = reader.readSmallUleb128() - 1;
out.annotateTo(reader.getOffset(), "type_idx = %s", TypeIdItem.getOptionalReferenceAnnotation(dexFile, typeIndex));
int sigIndex = reader.readSmallUleb128() - 1;
out.annotateTo(reader.getOffset(), "sig_idx = %s", StringIdItem.getOptionalReferenceAnnotation(dexFile, sigIndex, true));
out.deindent();
break;
}
case DebugItemType.END_LOCAL:
{
out.annotateTo(reader.getOffset(), "DBG_END_LOCAL");
out.indent();
int registerNum = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "register_num = v%d", registerNum);
out.deindent();
break;
}
case DebugItemType.RESTART_LOCAL:
{
out.annotateTo(reader.getOffset(), "DBG_RESTART_LOCAL");
out.indent();
int registerNum = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "register_num = v%d", registerNum);
out.deindent();
break;
}
case DebugItemType.PROLOGUE_END:
{
out.annotateTo(reader.getOffset(), "DBG_SET_PROLOGUE_END");
break;
}
case DebugItemType.EPILOGUE_BEGIN:
{
out.annotateTo(reader.getOffset(), "DBG_SET_EPILOGUE_BEGIN");
break;
}
case DebugItemType.SET_SOURCE_FILE:
{
out.annotateTo(reader.getOffset(), "DBG_SET_FILE");
out.indent();
int nameIdx = reader.readSmallUleb128() - 1;
out.annotateTo(reader.getOffset(), "name_idx = %s", StringIdItem.getOptionalReferenceAnnotation(dexFile, nameIdx));
out.deindent();
break;
}
default:
int adjusted = opcode - 0x0A;
int addressDiff = adjusted / 15;
int lineDiff = (adjusted % 15) - 4;
codeAddress += addressDiff;
lineNumber += lineDiff;
out.annotateTo(reader.getOffset(), "address_diff = +0x%x:0x%x, line_diff = +%d:%d, ", addressDiff, codeAddress, lineDiff, lineNumber);
break;
}
}
out.deindent();
}
};
}
use of org.jf.dexlib2.iface.debug.LineNumber in project smali by JesusFreke.
the class DexWriter method writeDebugItem.
private int writeDebugItem(@Nonnull DexDataWriter writer, @Nonnull DebugWriter<StringKey, TypeKey> debugWriter, @Nullable Iterable<? extends StringKey> parameterNames, @Nullable Iterable<? extends DebugItem> debugItems) throws IOException {
int parameterCount = 0;
int lastNamedParameterIndex = -1;
if (parameterNames != null) {
parameterCount = Iterables.size(parameterNames);
int index = 0;
for (StringKey parameterName : parameterNames) {
if (parameterName != null) {
lastNamedParameterIndex = index;
}
index++;
}
}
if (lastNamedParameterIndex == -1 && (debugItems == null || Iterables.isEmpty(debugItems))) {
return NO_OFFSET;
}
numDebugInfoItems++;
int debugItemOffset = writer.getPosition();
int startingLineNumber = 0;
if (debugItems != null) {
for (org.jf.dexlib2.iface.debug.DebugItem debugItem : debugItems) {
if (debugItem instanceof LineNumber) {
startingLineNumber = ((LineNumber) debugItem).getLineNumber();
break;
}
}
}
writer.writeUleb128(startingLineNumber);
writer.writeUleb128(parameterCount);
if (parameterNames != null) {
int index = 0;
for (StringKey parameterName : parameterNames) {
if (index == parameterCount) {
break;
}
index++;
writer.writeUleb128(stringSection.getNullableItemIndex(parameterName) + 1);
}
}
if (debugItems != null) {
debugWriter.reset(startingLineNumber);
for (DebugItem debugItem : debugItems) {
classSection.writeDebugItem(debugWriter, debugItem);
}
}
// write an END_SEQUENCE opcode, to end the debug item
writer.write(0);
return debugItemOffset;
}
Aggregations