use of org.jf.dexlib2.util.AnnotatedBytes in project smali by JesusFreke.
the class CodeItem method makeAnnotator.
@Nonnull
public static SectionAnnotator makeAnnotator(@Nonnull DexAnnotator annotator, @Nonnull MapItem mapItem) {
return new SectionAnnotator(annotator, mapItem) {
private SectionAnnotator debugInfoAnnotator = null;
@Override
public void annotateSection(@Nonnull AnnotatedBytes out) {
debugInfoAnnotator = annotator.getAnnotator(ItemType.DEBUG_INFO_ITEM);
super.annotateSection(out);
}
@Nonnull
@Override
public String getItemName() {
return "code_item";
}
@Override
public int getItemAlignment() {
return 4;
}
@Override
public void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
try {
DexReader reader = dexFile.readerAt(out.getCursor());
int registers = reader.readUshort();
out.annotate(2, "registers_size = %d", registers);
int inSize = reader.readUshort();
out.annotate(2, "ins_size = %d", inSize);
int outSize = reader.readUshort();
out.annotate(2, "outs_size = %d", outSize);
int triesCount = reader.readUshort();
out.annotate(2, "tries_size = %d", triesCount);
int debugInfoOffset = reader.readInt();
out.annotate(4, "debug_info_off = 0x%x", debugInfoOffset);
if (debugInfoOffset > 0) {
addDebugInfoIdentity(debugInfoOffset, itemIdentity);
}
int instructionSize = reader.readSmallUint();
out.annotate(4, "insns_size = 0x%x", instructionSize);
out.annotate(0, "instructions:");
out.indent();
out.setLimit(out.getCursor(), out.getCursor() + instructionSize * 2);
int end = reader.getOffset() + instructionSize * 2;
try {
while (reader.getOffset() < end) {
Instruction instruction = DexBackedInstruction.readFrom(reader);
// if we read past the end of the instruction list
if (reader.getOffset() > end) {
out.annotateTo(end, "truncated instruction");
reader.setOffset(end);
} else {
switch(instruction.getOpcode().format) {
case Format10x:
annotateInstruction10x(out, instruction);
break;
case Format35c:
annotateInstruction35c(out, (Instruction35c) instruction);
break;
case Format3rc:
annotateInstruction3rc(out, (Instruction3rc) instruction);
break;
case ArrayPayload:
annotateArrayPayload(out, (ArrayPayload) instruction);
break;
case PackedSwitchPayload:
annotatePackedSwitchPayload(out, (PackedSwitchPayload) instruction);
break;
case SparseSwitchPayload:
annotateSparseSwitchPayload(out, (SparseSwitchPayload) instruction);
break;
default:
annotateDefaultInstruction(out, instruction);
break;
}
}
assert reader.getOffset() == out.getCursor();
}
} catch (ExceptionWithContext ex) {
ex.printStackTrace(System.err);
out.annotate(0, "annotation error: %s", ex.getMessage());
out.moveTo(end);
reader.setOffset(end);
} finally {
out.clearLimit();
out.deindent();
}
if (triesCount > 0) {
if ((reader.getOffset() % 4) != 0) {
reader.readUshort();
out.annotate(2, "padding");
}
out.annotate(0, "try_items:");
out.indent();
try {
for (int i = 0; i < triesCount; i++) {
out.annotate(0, "try_item[%d]:", i);
out.indent();
try {
int startAddr = reader.readSmallUint();
out.annotate(4, "start_addr = 0x%x", startAddr);
int instructionCount = reader.readUshort();
out.annotate(2, "insn_count = 0x%x", instructionCount);
int handlerOffset = reader.readUshort();
out.annotate(2, "handler_off = 0x%x", handlerOffset);
} finally {
out.deindent();
}
}
} finally {
out.deindent();
}
int handlerListCount = reader.readSmallUleb128();
out.annotate(0, "encoded_catch_handler_list:");
out.annotateTo(reader.getOffset(), "size = %d", handlerListCount);
out.indent();
try {
for (int i = 0; i < handlerListCount; i++) {
out.annotate(0, "encoded_catch_handler[%d]", i);
out.indent();
try {
int handlerCount = reader.readSleb128();
out.annotateTo(reader.getOffset(), "size = %d", handlerCount);
boolean hasCatchAll = handlerCount <= 0;
handlerCount = Math.abs(handlerCount);
if (handlerCount != 0) {
out.annotate(0, "handlers:");
out.indent();
try {
for (int j = 0; j < handlerCount; j++) {
out.annotate(0, "encoded_type_addr_pair[%d]", i);
out.indent();
try {
int typeIndex = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), TypeIdItem.getReferenceAnnotation(dexFile, typeIndex));
int handlerAddress = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "addr = 0x%x", handlerAddress);
} finally {
out.deindent();
}
}
} finally {
out.deindent();
}
}
if (hasCatchAll) {
int catchAllAddress = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "catch_all_addr = 0x%x", catchAllAddress);
}
} finally {
out.deindent();
}
}
} finally {
out.deindent();
}
}
} catch (ExceptionWithContext ex) {
out.annotate(0, "annotation error: %s", ex.getMessage());
}
}
private String formatRegister(int registerNum) {
return String.format("v%d", registerNum);
}
private void annotateInstruction10x(@Nonnull AnnotatedBytes out, @Nonnull Instruction instruction) {
out.annotate(2, instruction.getOpcode().name);
}
private void annotateInstruction35c(@Nonnull AnnotatedBytes out, @Nonnull Instruction35c instruction) {
List<String> args = Lists.newArrayList();
int registerCount = instruction.getRegisterCount();
if (registerCount == 1) {
args.add(formatRegister(instruction.getRegisterC()));
} else if (registerCount == 2) {
args.add(formatRegister(instruction.getRegisterC()));
args.add(formatRegister(instruction.getRegisterD()));
} else if (registerCount == 3) {
args.add(formatRegister(instruction.getRegisterC()));
args.add(formatRegister(instruction.getRegisterD()));
args.add(formatRegister(instruction.getRegisterE()));
} else if (registerCount == 4) {
args.add(formatRegister(instruction.getRegisterC()));
args.add(formatRegister(instruction.getRegisterD()));
args.add(formatRegister(instruction.getRegisterE()));
args.add(formatRegister(instruction.getRegisterF()));
} else if (registerCount == 5) {
args.add(formatRegister(instruction.getRegisterC()));
args.add(formatRegister(instruction.getRegisterD()));
args.add(formatRegister(instruction.getRegisterE()));
args.add(formatRegister(instruction.getRegisterF()));
args.add(formatRegister(instruction.getRegisterG()));
}
String reference = ReferenceUtil.getReferenceString(instruction.getReference());
out.annotate(6, String.format("%s {%s}, %s", instruction.getOpcode().name, Joiner.on(", ").join(args), reference));
}
private void annotateInstruction3rc(@Nonnull AnnotatedBytes out, @Nonnull Instruction3rc instruction) {
int startRegister = instruction.getStartRegister();
int endRegister = startRegister + instruction.getRegisterCount() - 1;
String reference = ReferenceUtil.getReferenceString(instruction.getReference());
out.annotate(6, String.format("%s {%s .. %s}, %s", instruction.getOpcode().name, formatRegister(startRegister), formatRegister(endRegister), reference));
}
private void annotateDefaultInstruction(@Nonnull AnnotatedBytes out, @Nonnull Instruction instruction) {
List<String> args = Lists.newArrayList();
if (instruction instanceof OneRegisterInstruction) {
args.add(formatRegister(((OneRegisterInstruction) instruction).getRegisterA()));
if (instruction instanceof TwoRegisterInstruction) {
args.add(formatRegister(((TwoRegisterInstruction) instruction).getRegisterB()));
if (instruction instanceof ThreeRegisterInstruction) {
args.add(formatRegister(((ThreeRegisterInstruction) instruction).getRegisterC()));
}
}
} else if (instruction instanceof VerificationErrorInstruction) {
String verificationError = VerificationError.getVerificationErrorName(((VerificationErrorInstruction) instruction).getVerificationError());
if (verificationError != null) {
args.add(verificationError);
} else {
args.add("invalid verification error type");
}
}
if (instruction instanceof ReferenceInstruction) {
args.add(ReferenceUtil.getReferenceString(((ReferenceInstruction) instruction).getReference()));
} else if (instruction instanceof OffsetInstruction) {
int offset = ((OffsetInstruction) instruction).getCodeOffset();
String sign = offset >= 0 ? "+" : "-";
args.add(String.format("%s0x%x", sign, Math.abs(offset)));
} else if (instruction instanceof NarrowLiteralInstruction) {
int value = ((NarrowLiteralInstruction) instruction).getNarrowLiteral();
if (NumberUtils.isLikelyFloat(value)) {
args.add(String.format("%d # %f", value, Float.intBitsToFloat(value)));
} else {
args.add(String.format("%d", value));
}
} else if (instruction instanceof WideLiteralInstruction) {
long value = ((WideLiteralInstruction) instruction).getWideLiteral();
if (NumberUtils.isLikelyDouble(value)) {
args.add(String.format("%d # %f", value, Double.longBitsToDouble(value)));
} else {
args.add(String.format("%d", value));
}
} else if (instruction instanceof FieldOffsetInstruction) {
int fieldOffset = ((FieldOffsetInstruction) instruction).getFieldOffset();
args.add(String.format("field@0x%x", fieldOffset));
} else if (instruction instanceof VtableIndexInstruction) {
int vtableIndex = ((VtableIndexInstruction) instruction).getVtableIndex();
args.add(String.format("vtable@%d", vtableIndex));
} else if (instruction instanceof InlineIndexInstruction) {
int inlineIndex = ((InlineIndexInstruction) instruction).getInlineIndex();
args.add(String.format("inline@%d", inlineIndex));
}
out.annotate(instruction.getCodeUnits() * 2, "%s %s", instruction.getOpcode().name, Joiner.on(", ").join(args));
}
private void annotateArrayPayload(@Nonnull AnnotatedBytes out, @Nonnull ArrayPayload instruction) {
List<Number> elements = instruction.getArrayElements();
int elementWidth = instruction.getElementWidth();
out.annotate(2, instruction.getOpcode().name);
out.indent();
out.annotate(2, "element_width = %d", elementWidth);
out.annotate(4, "size = %d", elements.size());
out.annotate(0, "elements:");
out.indent();
for (int i = 0; i < elements.size(); i++) {
if (elementWidth == 8) {
long value = elements.get(i).longValue();
if (NumberUtils.isLikelyDouble(value)) {
out.annotate(elementWidth, "element[%d] = %d # %f", i, value, Double.longBitsToDouble(value));
} else {
out.annotate(elementWidth, "element[%d] = %d", i, value);
}
} else {
int value = elements.get(i).intValue();
if (NumberUtils.isLikelyFloat(value)) {
out.annotate(elementWidth, "element[%d] = %d # %f", i, value, Float.intBitsToFloat(value));
} else {
out.annotate(elementWidth, "element[%d] = %d", i, value);
}
}
}
if (out.getCursor() % 2 != 0) {
out.annotate(1, "padding");
}
out.deindent();
out.deindent();
}
private void annotatePackedSwitchPayload(@Nonnull AnnotatedBytes out, @Nonnull PackedSwitchPayload instruction) {
List<? extends SwitchElement> elements = instruction.getSwitchElements();
out.annotate(2, instruction.getOpcode().name);
out.indent();
out.annotate(2, "size = %d", elements.size());
if (elements.size() == 0) {
out.annotate(4, "first_key");
} else {
out.annotate(4, "first_key = %d", elements.get(0).getKey());
out.annotate(0, "targets:");
out.indent();
for (int i = 0; i < elements.size(); i++) {
out.annotate(4, "target[%d] = %d", i, elements.get(i).getOffset());
}
out.deindent();
}
out.deindent();
}
private void annotateSparseSwitchPayload(@Nonnull AnnotatedBytes out, @Nonnull SparseSwitchPayload instruction) {
List<? extends SwitchElement> elements = instruction.getSwitchElements();
out.annotate(2, instruction.getOpcode().name);
out.indent();
out.annotate(2, "size = %d", elements.size());
if (elements.size() > 0) {
out.annotate(0, "keys:");
out.indent();
for (int i = 0; i < elements.size(); i++) {
out.annotate(4, "key[%d] = %d", i, elements.get(i).getKey());
}
out.deindent();
out.annotate(0, "targets:");
out.indent();
for (int i = 0; i < elements.size(); i++) {
out.annotate(4, "target[%d] = %d", i, elements.get(i).getOffset());
}
out.deindent();
}
out.deindent();
}
private void addDebugInfoIdentity(int debugInfoOffset, String methodString) {
if (debugInfoAnnotator != null) {
debugInfoAnnotator.setItemIdentity(debugInfoOffset, methodString);
}
}
};
}
use of org.jf.dexlib2.util.AnnotatedBytes 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.getBuffer().readerAt(out.getCursor());
int lineStart = reader.readBigUleb128();
out.annotateTo(reader.getOffset(), "line_start = %d", lineStart & 0xFFFFFFFFL);
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.util.AnnotatedBytes in project smali by JesusFreke.
the class StringDataItem method makeAnnotator.
@Nonnull
public static SectionAnnotator makeAnnotator(@Nonnull DexAnnotator annotator, @Nonnull MapItem mapItem) {
return new SectionAnnotator(annotator, mapItem) {
@Nonnull
@Override
public String getItemName() {
return "string_data_item";
}
@Override
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
DexReader reader = dexFile.getBuffer().readerAt(out.getCursor());
int utf16Length = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "utf16_size = %d", utf16Length);
String value = reader.readString(utf16Length);
out.annotateTo(reader.getOffset() + 1, "data = \"%s\"", StringUtils.escapeString(value));
}
};
}
use of org.jf.dexlib2.util.AnnotatedBytes in project smali by JesusFreke.
the class HiddenApiClassDataItem method makeAnnotator.
@Nonnull
public static SectionAnnotator makeAnnotator(@Nonnull DexAnnotator annotator, @Nonnull MapItem mapItem) {
return new SectionAnnotator(annotator, mapItem) {
@Nonnull
@Override
public String getItemName() {
return "hiddenapi_class_data_item";
}
@Override
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
int startOffset = out.getCursor();
out.annotate(4, "size = 0x%x", dexFile.getDataBuffer().readSmallUint(out.getCursor()));
int index = 0;
for (ClassDef classDef : dexFile.getClasses()) {
out.annotate(0, "[%d] %s", index, classDef);
out.indent();
int offset = dexFile.getDataBuffer().readSmallUint(out.getCursor());
if (offset == 0) {
out.annotate(4, "offset = 0x%x", offset);
} else {
out.annotate(4, "offset = 0x%x (absolute offset: 0x%x)", offset, startOffset + offset);
}
int nextOffset = out.getCursor();
if (offset > 0) {
out.deindent();
out.moveTo(startOffset + offset);
DexReader<? extends DexBuffer> reader = dexFile.getBuffer().readerAt(out.getCursor());
for (Field field : classDef.getStaticFields()) {
out.annotate(0, "%s:", field);
out.indent();
int restrictions = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "restriction = 0x%x: %s", restrictions, HiddenApiRestriction.formatHiddenRestrictions(restrictions));
out.deindent();
}
for (Field field : classDef.getInstanceFields()) {
out.annotate(0, "%s:", field);
out.indent();
int restrictions = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "restriction = 0x%x: %s", restrictions, HiddenApiRestriction.formatHiddenRestrictions(restrictions));
out.deindent();
}
for (Method method : classDef.getDirectMethods()) {
out.annotate(0, "%s:", method);
out.indent();
int restrictions = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "restriction = 0x%x: %s", restrictions, HiddenApiRestriction.formatHiddenRestrictions(restrictions));
out.deindent();
}
for (Method method : classDef.getVirtualMethods()) {
out.annotate(0, "%s:", method);
out.indent();
int restrictions = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "restriction = 0x%x: %s", restrictions, HiddenApiRestriction.formatHiddenRestrictions(restrictions));
out.deindent();
}
out.indent();
}
out.moveTo(nextOffset);
out.deindent();
index++;
}
}
};
}
use of org.jf.dexlib2.util.AnnotatedBytes in project smali by JesusFreke.
the class ClassDataItem method makeAnnotator.
@Nonnull
public static SectionAnnotator makeAnnotator(@Nonnull DexAnnotator annotator, @Nonnull MapItem mapItem) {
return new SectionAnnotator(annotator, mapItem) {
private SectionAnnotator codeItemAnnotator = null;
@Override
public void annotateSection(@Nonnull AnnotatedBytes out) {
codeItemAnnotator = annotator.getAnnotator(ItemType.CODE_ITEM);
super.annotateSection(out);
}
@Nonnull
@Override
public String getItemName() {
return "class_data_item";
}
@Override
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
DexReader reader = dexFile.getBuffer().readerAt(out.getCursor());
int staticFieldsSize = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "static_fields_size = %d", staticFieldsSize);
int instanceFieldsSize = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "instance_fields_size = %d", instanceFieldsSize);
int directMethodsSize = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "direct_methods_size = %d", directMethodsSize);
int virtualMethodsSize = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "virtual_methods_size = %d", virtualMethodsSize);
int previousIndex = 0;
if (staticFieldsSize > 0) {
out.annotate(0, "static_fields:");
out.indent();
for (int i = 0; i < staticFieldsSize; i++) {
out.annotate(0, "static_field[%d]", i);
out.indent();
previousIndex = annotateEncodedField(out, dexFile, reader, previousIndex);
out.deindent();
}
out.deindent();
}
if (instanceFieldsSize > 0) {
out.annotate(0, "instance_fields:");
out.indent();
previousIndex = 0;
for (int i = 0; i < instanceFieldsSize; i++) {
out.annotate(0, "instance_field[%d]", i);
out.indent();
previousIndex = annotateEncodedField(out, dexFile, reader, previousIndex);
out.deindent();
}
out.deindent();
}
if (directMethodsSize > 0) {
out.annotate(0, "direct_methods:");
out.indent();
previousIndex = 0;
for (int i = 0; i < directMethodsSize; i++) {
out.annotate(0, "direct_method[%d]", i);
out.indent();
previousIndex = annotateEncodedMethod(out, dexFile, reader, previousIndex);
out.deindent();
}
out.deindent();
}
if (virtualMethodsSize > 0) {
out.annotate(0, "virtual_methods:");
out.indent();
previousIndex = 0;
for (int i = 0; i < virtualMethodsSize; i++) {
out.annotate(0, "virtual_method[%d]", i);
out.indent();
previousIndex = annotateEncodedMethod(out, dexFile, reader, previousIndex);
out.deindent();
}
out.deindent();
}
}
private int annotateEncodedField(@Nonnull AnnotatedBytes out, @Nonnull DexBackedDexFile dexFile, @Nonnull DexReader reader, int previousIndex) {
// large values may be used for the index delta, which cause the cumulative index to overflow upon
// addition, effectively allowing out of order entries.
int indexDelta = reader.readLargeUleb128();
int fieldIndex = previousIndex + indexDelta;
out.annotateTo(reader.getOffset(), "field_idx_diff = %d: %s", indexDelta, FieldIdItem.getReferenceAnnotation(dexFile, fieldIndex));
int accessFlags = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "access_flags = 0x%x: %s", accessFlags, Joiner.on('|').join(AccessFlags.getAccessFlagsForField(accessFlags)));
return fieldIndex;
}
private int annotateEncodedMethod(@Nonnull AnnotatedBytes out, @Nonnull DexBackedDexFile dexFile, @Nonnull DexReader reader, int previousIndex) {
// large values may be used for the index delta, which cause the cumulative index to overflow upon
// addition, effectively allowing out of order entries.
int indexDelta = reader.readLargeUleb128();
int methodIndex = previousIndex + indexDelta;
out.annotateTo(reader.getOffset(), "method_idx_diff = %d: %s", indexDelta, MethodIdItem.getReferenceAnnotation(dexFile, methodIndex));
int accessFlags = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "access_flags = 0x%x: %s", accessFlags, Joiner.on('|').join(AccessFlags.getAccessFlagsForMethod(accessFlags)));
int codeOffset = reader.readSmallUleb128();
if (codeOffset == 0) {
out.annotateTo(reader.getOffset(), "code_off = code_item[NO_OFFSET]");
} else {
out.annotateTo(reader.getOffset(), "code_off = code_item[0x%x]", codeOffset);
addCodeItemIdentity(codeOffset, MethodIdItem.asString(dexFile, methodIndex));
}
return methodIndex;
}
private void addCodeItemIdentity(int codeItemOffset, String methodString) {
if (codeItemAnnotator != null) {
codeItemAnnotator.setItemIdentity(codeItemOffset, methodString);
}
}
};
}
Aggregations