mirror of
https://github.com/revanced/smali.git
synced 2025-05-06 09:24:33 +02:00
Changes to dump annotation format
git-svn-id: https://smali.googlecode.com/svn/trunk@398 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
parent
d9dd571427
commit
4d68e05fb5
@ -177,25 +177,49 @@ public class AnnotationDirectoryItem extends Item<AnnotationDirectoryItem> {
|
||||
/** {@inheritDoc} */
|
||||
protected void writeItem(AnnotatedOutput out) {
|
||||
if (out.annotates()) {
|
||||
out.annotate(4, "class_annotations_off");
|
||||
out.annotate(4, "annotated_fields_size");
|
||||
out.annotate(4, "annotated_methods_size");
|
||||
out.annotate(4, "annotated_parameters_size");
|
||||
if (!isInternable() && parent != null) {
|
||||
out.annotate(0, parent.getClassType().getTypeDescriptor());
|
||||
}
|
||||
if (classAnnotations != null) {
|
||||
out.annotate(4, "class_annotations_off: 0x" + Integer.toHexString(classAnnotations.getOffset()));
|
||||
} else {
|
||||
out.annotate(4, "class_annotations_off:");
|
||||
}
|
||||
|
||||
out.annotate(4, "annotated_fields_size: 0x" + Integer.toHexString(fieldAnnotations.length) + " (" +
|
||||
fieldAnnotations.length + ")");
|
||||
out.annotate(4, "annotated_methods_size: 0x" + Integer.toHexString(methodAnnotations.length) + " (" +
|
||||
methodAnnotations.length + ")");
|
||||
out.annotate(4, "annotated_parameters_size: 0x" + Integer.toHexString(parameterAnnotations.length) + " (" +
|
||||
parameterAnnotations.length + ")");
|
||||
|
||||
|
||||
int index = 0;
|
||||
for (int i=0; i<fieldAnnotations.length; i++) {
|
||||
out.annotate(4, "field_idx");
|
||||
out.annotate(4, "annotations_off");
|
||||
out.annotate(0, "[" + index++ + "] field_annotation");
|
||||
|
||||
out.indent();
|
||||
out.annotate(4, "field: " + fieldAnnotationFields[i].getFieldName().getStringValue() + ":" +
|
||||
fieldAnnotationFields[i].getFieldType().getTypeDescriptor());
|
||||
out.annotate(4, "annotations_off: 0x" + Integer.toHexString(fieldAnnotations[i].getOffset()));
|
||||
out.deindent();
|
||||
}
|
||||
|
||||
index = 0;
|
||||
for (int i=0; i<methodAnnotations.length; i++) {
|
||||
out.annotate(4, "method_idx");
|
||||
out.annotate(4, "annotations_off");
|
||||
out.annotate(0, "[" + index++ + "] method_annotation");
|
||||
out.indent();
|
||||
out.annotate(4, "method: " + methodAnnotationMethods[i].getMethodString());
|
||||
out.annotate(4, "annotations_off: 0x" + Integer.toHexString(methodAnnotations[i].getOffset()));
|
||||
out.deindent();
|
||||
}
|
||||
|
||||
index = 0;
|
||||
for (int i=0; i<parameterAnnotations.length; i++) {
|
||||
out.annotate(4, "method_idx");
|
||||
out.annotate(4, "annotations_off");
|
||||
out.annotate(0, "[" + index++ + "] parameter_annotation");
|
||||
out.indent();
|
||||
out.annotate(4, "method: " + parameterAnnotationMethods[i].getMethodString());
|
||||
out.annotate(4, "annotations_off: 0x" + Integer.toHexString(parameterAnnotations[i].getOffset()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,9 +88,8 @@ public class AnnotationItem extends Item<AnnotationItem> {
|
||||
/** {@inheritDoc} */
|
||||
protected void writeItem(AnnotatedOutput out) {
|
||||
if (out.annotates()) {
|
||||
out.annotate("visibility");
|
||||
out.annotate("visibility: " + visibility.name());
|
||||
out.writeByte(visibility.value);
|
||||
out.annotate("annotation");
|
||||
annotationValue.writeValue(out);
|
||||
}else {
|
||||
out.writeByte(visibility.value);
|
||||
|
@ -84,9 +84,10 @@ public class AnnotationSetItem extends Item<AnnotationSetItem> {
|
||||
/** {@inheritDoc} */
|
||||
protected void writeItem(AnnotatedOutput out) {
|
||||
if (out.annotates()) {
|
||||
out.annotate(4, "size");
|
||||
for (int i=0; i<annotations.length; i++) {
|
||||
out.annotate(4, "annotation_off");
|
||||
out.annotate(4, "size: 0x" + Integer.toHexString(annotations.length) + " (" + annotations.length + ")");
|
||||
for (AnnotationItem annotationItem: annotations) {
|
||||
out.annotate(4, "annotation_off: 0x" + Integer.toHexString(annotationItem.getOffset()) + " - " +
|
||||
annotationItem.getEncodedAnnotation().annotationType.getTypeDescriptor());
|
||||
}
|
||||
}
|
||||
out.writeInt(annotations.length);
|
||||
|
@ -85,9 +85,10 @@ public class AnnotationSetRefList extends Item<AnnotationSetRefList> {
|
||||
/** {@inheritDoc} */
|
||||
protected void writeItem(AnnotatedOutput out) {
|
||||
if (out.annotates()) {
|
||||
out.annotate(4, "size");
|
||||
out.annotate(4, "size: 0x" + Integer.toHexString(annotationSets.length) + " (" + annotationSets.length +
|
||||
")");
|
||||
for (AnnotationSetItem annotationSetItem: annotationSets) {
|
||||
out.annotate(4, "annotation_set_off");
|
||||
out.annotate(4, "annotation_set_off: 0x" + Integer.toHexString(annotationSetItem.getOffset()));
|
||||
}
|
||||
}
|
||||
out.writeInt(annotationSets.length);
|
||||
|
@ -147,36 +147,56 @@ public class ClassDataItem extends Item<ClassDataItem> {
|
||||
/** {@inheritDoc} */
|
||||
protected void writeItem(AnnotatedOutput out) {
|
||||
if (out.annotates()) {
|
||||
out.annotate("static_fields_size");
|
||||
out.annotate("static_fields_size: 0x" + Integer.toHexString(staticFields.length) + " (" +
|
||||
staticFields.length + ")");
|
||||
out.writeUnsignedLeb128(staticFields.length);
|
||||
out.annotate("instance_fields_size");
|
||||
out.annotate("instance_fields_size: 0x" + Integer.toHexString(instanceFields.length) + " (" +
|
||||
instanceFields.length + ")");
|
||||
out.writeUnsignedLeb128(instanceFields.length);
|
||||
out.annotate("direct_methods_size");
|
||||
out.annotate("direct_methods_size: 0x" + Integer.toHexString(directMethods.length) + " (" +
|
||||
directMethods.length + ")");
|
||||
out.writeUnsignedLeb128(directMethods.length);
|
||||
out.annotate("virtual_methods_size");
|
||||
out.annotate("virtual_methods_size: 0x" + Integer.toHexString(virtualMethods.length) + " (" +
|
||||
virtualMethods.length + ")");
|
||||
out.writeUnsignedLeb128(virtualMethods.length);
|
||||
|
||||
int index = 0;
|
||||
EncodedField previousEncodedField = null;
|
||||
for (EncodedField encodedField: staticFields) {
|
||||
out.annotate("[" + index++ + "] static_field");
|
||||
out.indent();
|
||||
encodedField.writeTo(out, previousEncodedField);
|
||||
out.deindent();
|
||||
previousEncodedField = encodedField;
|
||||
}
|
||||
|
||||
index = 0;
|
||||
previousEncodedField = null;
|
||||
for (EncodedField encodedField: instanceFields) {
|
||||
out.annotate("[" + index++ + "] instance_field");
|
||||
out.indent();
|
||||
encodedField.writeTo(out, previousEncodedField);
|
||||
out.deindent();
|
||||
previousEncodedField = encodedField;
|
||||
}
|
||||
|
||||
index = 0;
|
||||
EncodedMethod previousEncodedMethod = null;
|
||||
for (EncodedMethod encodedMethod: directMethods) {
|
||||
out.annotate("[" + index++ + "] direct_method");
|
||||
out.indent();
|
||||
encodedMethod.writeTo(out, previousEncodedMethod);
|
||||
out.deindent();
|
||||
previousEncodedMethod = encodedMethod;
|
||||
}
|
||||
|
||||
index = 0;
|
||||
previousEncodedMethod = null;
|
||||
for (EncodedMethod encodedMethod: virtualMethods) {
|
||||
out.annotate("[" + index++ + "] virtual_method");
|
||||
out.indent();
|
||||
encodedMethod.writeTo(out, previousEncodedMethod);
|
||||
out.deindent();
|
||||
previousEncodedMethod = encodedMethod;
|
||||
}
|
||||
} else {
|
||||
@ -315,9 +335,9 @@ public class ClassDataItem extends Item<ClassDataItem> {
|
||||
int previousIndex = previousEncodedField==null?0:previousEncodedField.field.getIndex();
|
||||
|
||||
if (out.annotates()) {
|
||||
out.annotate("field_idx_diff");
|
||||
out.annotate("field: " + field.getFieldString());
|
||||
out.writeUnsignedLeb128(field.getIndex() - previousIndex);
|
||||
out.annotate("access_flags");
|
||||
out.annotate("access_flags: " + AccessFlags.formatAccessFlagsForField(accessFlags));
|
||||
out.writeUnsignedLeb128(accessFlags);
|
||||
}else {
|
||||
out.writeUnsignedLeb128(field.getIndex() - previousIndex);
|
||||
@ -422,12 +442,17 @@ public class ClassDataItem extends Item<ClassDataItem> {
|
||||
int previousIndex = previousEncodedMethod==null?0:previousEncodedMethod.method.getIndex();
|
||||
|
||||
if (out.annotates()) {
|
||||
out.annotate("method_idx_diff");
|
||||
out.annotate("method: " + method.getMethodString());
|
||||
out.writeUnsignedLeb128(method.getIndex() - previousIndex);
|
||||
out.annotate("access_flags");
|
||||
out.annotate("access_flags: " + AccessFlags.formatAccessFlagsForMethod(accessFlags));
|
||||
out.writeUnsignedLeb128(accessFlags);
|
||||
out.annotate("code_off");
|
||||
out.writeUnsignedLeb128(codeItem==null?0:codeItem.getOffset());
|
||||
if (codeItem != null) {
|
||||
out.annotate("code_off: 0x" + codeItem.getOffset());
|
||||
out.writeUnsignedLeb128(codeItem.getOffset());
|
||||
} else {
|
||||
out.annotate("code_off: 0x0");
|
||||
out.writeUnsignedLeb128(0);
|
||||
}
|
||||
}else {
|
||||
out.writeUnsignedLeb128(method.getIndex() - previousIndex);
|
||||
out.writeUnsignedLeb128(accessFlags);
|
||||
|
@ -30,6 +30,7 @@ package org.jf.dexlib;
|
||||
|
||||
import org.jf.dexlib.Util.Input;
|
||||
import org.jf.dexlib.Util.AnnotatedOutput;
|
||||
import org.jf.dexlib.Util.AccessFlags;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@ -139,14 +140,18 @@ public class ClassDefItem extends Item<ClassDefItem> {
|
||||
/** {@inheritDoc} */
|
||||
protected void writeItem(AnnotatedOutput out) {
|
||||
if (out.annotates()) {
|
||||
out.annotate(4, "class_idx");
|
||||
out.annotate(4, "access_flags");
|
||||
out.annotate(4, "superclass_idx");
|
||||
out.annotate(4, "interfaces_off");
|
||||
out.annotate(4, "source_file_idx");
|
||||
out.annotate(4, "annotations_off");
|
||||
out.annotate(4, "class_data_off");
|
||||
out.annotate(4, "static_values_off");
|
||||
out.annotate(4, "class_type: " + classType.getTypeDescriptor());
|
||||
out.annotate(4, "access_flags: " + AccessFlags.formatAccessFlagsForClass(accessFlags));
|
||||
out.annotate(4, "superclass_type: " + (superType==null?"":superType.getTypeDescriptor()));
|
||||
out.annotate(4, "interfaces: " +
|
||||
(implementedInterfaces==null?"":implementedInterfaces.getTypeListString(" ")));
|
||||
out.annotate(4, "source_file: " + (sourceFile==null?"":sourceFile.getStringValue()));
|
||||
out.annotate(4, "annotations_off: " +
|
||||
(annotations==null?"":"0x"+Integer.toHexString(annotations.getOffset())));
|
||||
out.annotate(4, "class_data_off:" +
|
||||
(classData==null?"":"0x"+Integer.toHexString(classData.getOffset())));
|
||||
out.annotate(4, "static_values_off: " +
|
||||
(staticFieldInitializers==null?"":"0x"+Integer.toHexString(staticFieldInitializers.getOffset())));
|
||||
}
|
||||
out.writeInt(classType.getIndex());
|
||||
out.writeInt(accessFlags);
|
||||
|
@ -186,33 +186,46 @@ public class CodeItem extends Item<CodeItem> {
|
||||
/** {@inheritDoc} */
|
||||
protected void writeItem(final AnnotatedOutput out) {
|
||||
if (out.annotates()) {
|
||||
out.annotate(2, "registers_size");
|
||||
out.annotate(2, "ins_size");
|
||||
out.annotate(2, "outs_size");
|
||||
out.annotate(2, "tries_size");
|
||||
out.annotate(4, "debug_info_off");
|
||||
out.annotate(4, "insns_size");
|
||||
out.annotate(0, parent.method.getMethodString());
|
||||
out.annotate(2, "registers_size: 0x" + Integer.toHexString(registerCount) + " (" + registerCount + ")");
|
||||
out.annotate(2, "ins_size: 0x" + Integer.toHexString(inWords) + " (" + inWords + ")");
|
||||
out.annotate(2, "outs_size: 0x" + Integer.toHexString(outWords) + " (" + outWords + ")");
|
||||
int triesLength = tries==null?0:tries.length;
|
||||
out.annotate(2, "tries_size: 0x" + Integer.toHexString(triesLength) + " (" + triesLength + ")");
|
||||
if (debugInfo == null) {
|
||||
out.annotate(4, "debug_info_off:");
|
||||
} else {
|
||||
out.annotate(4, "debug_info_off: 0x" + debugInfo.getOffset());
|
||||
}
|
||||
out.annotate(4, "insns_size: 0x" + Integer.toHexString(encodedInstructions.length / 2) + " (" +
|
||||
(encodedInstructions.length / 2) + ")");
|
||||
InstructionIterator.IterateInstructions(encodedInstructions,
|
||||
new InstructionIterator.ProcessRawInstructionDelegate() {
|
||||
|
||||
public void ProcessNormalInstruction(Opcode opcode, int index) {
|
||||
out.annotate(opcode.format.size, opcode.name + " instruction");
|
||||
out.annotate(opcode.format.size, "[0x" + Integer.toHexString(index/2) + "] " + opcode.name +
|
||||
" instruction");
|
||||
}
|
||||
|
||||
public void ProcessReferenceInstruction(Opcode opcode, int index) {
|
||||
out.annotate(opcode.format.size, opcode.name + " instruction");
|
||||
out.annotate(opcode.format.size, "[0x" + Integer.toHexString(index/2) + "] " + opcode.name +
|
||||
" instruction");
|
||||
}
|
||||
|
||||
public void ProcessPackedSwitchInstruction(int index, int targetCount, int instructionLength) {
|
||||
out.annotate(instructionLength, "packed_switch instruction");
|
||||
out.annotate(instructionLength, "[0x" + Integer.toHexString(index/2) + "] " +
|
||||
"packed_switch instruction");
|
||||
}
|
||||
|
||||
public void ProcessSparseSwitchInstruction(int index, int targetCount, int instructionLength) {
|
||||
out.annotate(instructionLength, "sparse_switch instruction");
|
||||
out.annotate(instructionLength, "[0x" + Integer.toHexString(index/2) + "] " +
|
||||
"sparse_switch instruction");
|
||||
}
|
||||
|
||||
public void ProcessFillArrayDataInstruction(int index, int elementWidth, int elementCount, int instructionLength) {
|
||||
out.annotate(instructionLength, "fill_array_data instruction");
|
||||
public void ProcessFillArrayDataInstruction(int index, int elementWidth, int elementCount,
|
||||
int instructionLength) {
|
||||
out.annotate(instructionLength, "[0x" + Integer.toHexString(index/2) + "] " +
|
||||
"fill_array_data instruction");
|
||||
}
|
||||
});
|
||||
if (tries != null && (tries.length % 2 == 1)) {
|
||||
@ -237,6 +250,32 @@ public class CodeItem extends Item<CodeItem> {
|
||||
InstructionWriter.writeInstructions(encodedInstructions, referencedItems, out);
|
||||
|
||||
if (tries != null && tries.length > 0) {
|
||||
if (out.annotates()) {
|
||||
if ((encodedInstructions.length % 4) != 0) {
|
||||
out.annotate("padding");
|
||||
out.writeShort(0);
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
for (TryItem tryItem: tries) {
|
||||
out.annotate(0, "[0x" + Integer.toHexString(index++) + "] try_item");
|
||||
out.indent();
|
||||
tryItem.writeTo(out);
|
||||
out.deindent();
|
||||
}
|
||||
|
||||
out.annotate("handler_count: 0x" + Integer.toHexString(encodedCatchHandlers.length) + "(" +
|
||||
encodedCatchHandlers.length + ")");
|
||||
out.writeUnsignedLeb128(encodedCatchHandlers.length);
|
||||
|
||||
index = 0;
|
||||
for (EncodedCatchHandler encodedCatchHandler: encodedCatchHandlers) {
|
||||
out.annotate(0, "[" + Integer.toHexString(index++) + "] encoded_catch_handler");
|
||||
out.indent();
|
||||
encodedCatchHandler.writeTo(out);
|
||||
out.deindent();
|
||||
}
|
||||
} else {
|
||||
if ((encodedInstructions.length % 4) != 0) {
|
||||
out.writeShort(0);
|
||||
}
|
||||
@ -252,6 +291,7 @@ public class CodeItem extends Item<CodeItem> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public ItemType getItemType() {
|
||||
@ -373,9 +413,10 @@ public class CodeItem extends Item<CodeItem> {
|
||||
*/
|
||||
private void writeTo(AnnotatedOutput out) {
|
||||
if (out.annotates()) {
|
||||
out.annotate(4, "start_addr");
|
||||
out.annotate(2, "insn_count");
|
||||
out.annotate(2, "handler_off");
|
||||
out.annotate(4, "start_addr: 0x" + Integer.toHexString(startAddress));
|
||||
out.annotate(2, "insn_count: 0x" + Integer.toHexString(instructionCount) + " (" + instructionCount +
|
||||
")");
|
||||
out.annotate(2, "handler_off: 0x" + Integer.toHexString(encodedCatchHandler.getOffsetInList()));
|
||||
}
|
||||
|
||||
out.writeInt(startAddress);
|
||||
@ -476,7 +517,7 @@ public class CodeItem extends Item<CodeItem> {
|
||||
*/
|
||||
private void writeTo(AnnotatedOutput out) {
|
||||
if (out.annotates()) {
|
||||
out.annotate("size");
|
||||
out.annotate("size: 0x" + Integer.toHexString(handlers.length) + " (" + handlers.length + ")");
|
||||
|
||||
int size = handlers.length;
|
||||
if (catchAllHandlerAddress < 0) {
|
||||
@ -484,12 +525,16 @@ public class CodeItem extends Item<CodeItem> {
|
||||
}
|
||||
out.writeSignedLeb128(size);
|
||||
|
||||
int index = 0;
|
||||
for (EncodedTypeAddrPair handler: handlers) {
|
||||
out.annotate(0, "[" + index++ + "] encoded_type_addr_pair");
|
||||
out.indent();
|
||||
handler.writeTo(out);
|
||||
out.deindent();
|
||||
}
|
||||
|
||||
if (catchAllHandlerAddress > -1) {
|
||||
out.annotate("catch_all_addr");
|
||||
out.annotate("catch_all_addr: 0x" + Integer.toHexString(catchAllHandlerAddress));
|
||||
out.writeUnsignedLeb128(catchAllHandlerAddress);
|
||||
}
|
||||
} else {
|
||||
@ -556,10 +601,10 @@ public class CodeItem extends Item<CodeItem> {
|
||||
*/
|
||||
private void writeTo(AnnotatedOutput out) {
|
||||
if (out.annotates()) {
|
||||
out.annotate("type_idx");
|
||||
out.annotate("exception_type: " + exceptionType.getTypeDescriptor());
|
||||
out.writeUnsignedLeb128(exceptionType.getIndex());
|
||||
|
||||
out.annotate("addr");
|
||||
out.annotate("handler_addr: 0x" + Integer.toHexString(handlerAddress));
|
||||
out.writeUnsignedLeb128(handlerAddress);
|
||||
} else {
|
||||
out.writeUnsignedLeb128(exceptionType.getIndex());
|
||||
|
@ -266,15 +266,15 @@ public class DebugInstructionIterator {
|
||||
{
|
||||
//TODO: add javadocs
|
||||
public void ProcessEndSequence(int startOffset) {
|
||||
ProcessStaticOpcode(startOffset, 1);
|
||||
ProcessStaticOpcode(DebugOpcode.DBG_END_SEQUENCE, startOffset, 1);
|
||||
}
|
||||
|
||||
public void ProcessAdvancePC(int startOffset, int length, int addressDiff) {
|
||||
ProcessStaticOpcode(startOffset, length);
|
||||
ProcessStaticOpcode(DebugOpcode.DBG_ADVANCE_PC, startOffset, length);
|
||||
}
|
||||
|
||||
public void ProcessAdvanceLine(int startOffset, int length, int lineDiff) {
|
||||
ProcessStaticOpcode(startOffset, length);
|
||||
ProcessStaticOpcode(DebugOpcode.DBG_ADVANCE_LINE, startOffset, length);
|
||||
}
|
||||
|
||||
public void ProcessStartLocal(int startOffset, int length, int registerNum, int nameIndex, int typeIndex,
|
||||
@ -286,29 +286,29 @@ public class DebugInstructionIterator {
|
||||
}
|
||||
|
||||
public void ProcessEndLocal(int startOffset, int length, int registerNum, boolean registerIsSigned) {
|
||||
ProcessStaticOpcode(startOffset, length);
|
||||
ProcessStaticOpcode(DebugOpcode.DBG_END_LOCAL, startOffset, length);
|
||||
}
|
||||
|
||||
public void ProcessRestartLocal(int startOffset, int length, int registerNum, boolean registerIsSigned) {
|
||||
ProcessStaticOpcode(startOffset, length);
|
||||
ProcessStaticOpcode(DebugOpcode.DBG_RESTART_LOCAL, startOffset, length);
|
||||
}
|
||||
|
||||
public void ProcessSetPrologueEnd(int startOffset) {
|
||||
ProcessStaticOpcode(startOffset, 1);
|
||||
ProcessStaticOpcode(DebugOpcode.DBG_SET_PROLOGUE_END, startOffset, 1);
|
||||
}
|
||||
|
||||
public void ProcessSetEpilogueBegin(int startOffset) {
|
||||
ProcessStaticOpcode(startOffset, 1);
|
||||
ProcessStaticOpcode(DebugOpcode.DBG_SET_EPILOGUE_BEGIN, startOffset, 1);
|
||||
}
|
||||
|
||||
public void ProcessSetFile(int startOffset, int length, int nameIndex) {
|
||||
}
|
||||
|
||||
public void ProcessSpecialOpcode(int startOffset, int debugOpcode, int lineDiff, int addressDiff) {
|
||||
ProcessStaticOpcode(startOffset, 1);
|
||||
ProcessStaticOpcode(DebugOpcode.DBG_SPECIAL_OPCODE, startOffset, 1);
|
||||
}
|
||||
|
||||
public void ProcessStaticOpcode(int startOffset, int length) {
|
||||
public void ProcessStaticOpcode(DebugOpcode debugOpcode, int startOffset, int length) {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ public enum DebugOpcode {
|
||||
DBG_END_LOCAL((byte)0x05),
|
||||
DBG_RESTART_LOCAL((byte)0x06),
|
||||
DBG_SET_PROLOGUE_END((byte)0x07),
|
||||
DBG_SET_EPILOGUE_END((byte)0x08),
|
||||
DBG_SET_EPILOGUE_BEGIN((byte)0x08),
|
||||
DBG_SET_FILE((byte)0x09),
|
||||
DBG_SPECIAL_OPCODE((byte)0x0A);
|
||||
|
||||
|
@ -187,7 +187,7 @@ public class DebugInfoItem extends Item<DebugInfoItem> {
|
||||
private int referencedItemsPosition = 0;
|
||||
|
||||
@Override
|
||||
public void ProcessStaticOpcode(int startOffset, int length) {
|
||||
public void ProcessStaticOpcode(DebugOpcode opcode, int startOffset, int length) {
|
||||
this.length+=length;
|
||||
}
|
||||
|
||||
@ -261,6 +261,19 @@ public class DebugInfoItem extends Item<DebugInfoItem> {
|
||||
|
||||
/** {@inheritDoc} */
|
||||
protected void writeItem(final AnnotatedOutput out) {
|
||||
|
||||
if (out.annotates()) {
|
||||
writeItemWithAnnotations(out);
|
||||
} else {
|
||||
writeItemWithNoAnnotations(out);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that writes the item, without writing annotations
|
||||
* @param out the AnnotatedOutput object
|
||||
*/
|
||||
private void writeItemWithNoAnnotations(final AnnotatedOutput out) {
|
||||
out.writeUnsignedLeb128(lineStart);
|
||||
out.writeUnsignedLeb128(parameterNames.length);
|
||||
for (StringIdItem parameterName: parameterNames) {
|
||||
@ -278,7 +291,7 @@ public class DebugInfoItem extends Item<DebugInfoItem> {
|
||||
private int referencedItemsPosition = 0;
|
||||
|
||||
@Override
|
||||
public void ProcessStaticOpcode(int startOffset, int length) {
|
||||
public void ProcessStaticOpcode(DebugOpcode opcode, int startOffset, int length) {
|
||||
out.write(encodedDebugInfo, startOffset, length);
|
||||
}
|
||||
|
||||
@ -342,6 +355,200 @@ public class DebugInfoItem extends Item<DebugInfoItem> {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that writes and annotates the item
|
||||
* @param out the AnnotatedOutput object
|
||||
*/
|
||||
private void writeItemWithAnnotations(final AnnotatedOutput out) {
|
||||
out.annotate(0, parent.getParent().method.getMethodString());
|
||||
out.annotate("line_start: 0x" + Integer.toHexString(lineStart) + " (" + lineStart + ")");
|
||||
out.writeUnsignedLeb128(lineStart);
|
||||
out.annotate("parameters_size: 0x" + Integer.toHexString(parameterNames.length) + " (" + parameterNames.length
|
||||
+ ")");
|
||||
out.writeUnsignedLeb128(parameterNames.length);
|
||||
int index = 0;
|
||||
for (StringIdItem parameterName: parameterNames) {
|
||||
int indexp1;
|
||||
if (parameterName == null) {
|
||||
out.annotate("[" + index++ +"] parameterName: ");
|
||||
indexp1 = 0;
|
||||
} else {
|
||||
out.annotate("[" + index++ +"] parameterName: " + parameterName.getStringValue());
|
||||
indexp1 = parameterName.getIndex() + 1;
|
||||
}
|
||||
out.writeUnsignedLeb128(indexp1);
|
||||
}
|
||||
|
||||
DebugInstructionIterator.IterateInstructions(new ByteArrayInput(encodedDebugInfo),
|
||||
new DebugInstructionIterator.ProcessRawDebugInstructionDelegate() {
|
||||
private int referencedItemsPosition = 0;
|
||||
|
||||
@Override
|
||||
public void ProcessEndSequence(int startOffset) {
|
||||
out.annotate("DBG_END_SEQUENCE");
|
||||
out.writeByte(DebugOpcode.DBG_END_SEQUENCE.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ProcessAdvancePC(int startOffset, int length, int addressDiff) {
|
||||
out.annotate("DBG_ADVANCE_PC");
|
||||
out.writeByte(DebugOpcode.DBG_ADVANCE_PC.value);
|
||||
out.indent();
|
||||
out.annotate("addr_diff: 0x" + Integer.toHexString(addressDiff) + " (" + addressDiff + ")");
|
||||
out.writeUnsignedLeb128(addressDiff);
|
||||
out.deindent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ProcessAdvanceLine(int startOffset, int length, int lineDiff) {
|
||||
out.annotate("DBG_ADVANCE_LINE");
|
||||
out.writeByte(DebugOpcode.DBG_ADVANCE_LINE.value);
|
||||
out.indent();
|
||||
out.annotate("line_diff: 0x" + Integer.toHexString(lineDiff) + " (" + lineDiff + ")");
|
||||
out.writeSignedLeb128(lineDiff);
|
||||
out.deindent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ProcessStartLocal(int startOffset, int length, int registerNum, int nameIndex,
|
||||
int typeIndex, boolean registerIsSigned) {
|
||||
out.annotate("DBG_START_LOCAL");
|
||||
out.writeByte(DebugOpcode.DBG_START_LOCAL.value);
|
||||
out.indent();
|
||||
out.annotate("register_num: 0x" + Integer.toHexString(registerNum) + " (" + registerNum + ")");
|
||||
if (dexFile.getPreserveSignedRegisters() && registerIsSigned) {
|
||||
out.writeSignedLeb128(registerNum);
|
||||
} else {
|
||||
out.writeUnsignedLeb128(registerNum);
|
||||
}
|
||||
if (nameIndex != -1) {
|
||||
Item nameItem = referencedItems[referencedItemsPosition++];
|
||||
assert nameItem instanceof StringIdItem;
|
||||
out.annotate("name: " + ((StringIdItem)nameItem).getStringValue());
|
||||
out.writeUnsignedLeb128(nameItem.getIndex() + 1);
|
||||
} else {
|
||||
out.annotate("name: ");
|
||||
out.writeByte(0);
|
||||
}
|
||||
if (typeIndex != -1) {
|
||||
Item typeItem = referencedItems[referencedItemsPosition++];
|
||||
assert typeItem instanceof TypeIdItem;
|
||||
out.annotate("type: " + ((TypeIdItem)typeItem).getTypeDescriptor());
|
||||
out.writeUnsignedLeb128(typeItem.getIndex() + 1);
|
||||
} else {
|
||||
out.annotate("type: ");
|
||||
out.writeByte(0);
|
||||
}
|
||||
out.deindent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ProcessStartLocalExtended(int startOffset, int length, int registerNum, int nameIndex,
|
||||
int typeIndex, int signatureIndex,
|
||||
boolean registerIsSigned) {
|
||||
out.annotate("DBG_START_LOCAL_EXTENDED");
|
||||
out.writeByte(DebugOpcode.DBG_START_LOCAL_EXTENDED.value);
|
||||
out.indent();
|
||||
out.annotate("register_num: 0x" + Integer.toHexString(registerNum) + " (" + registerNum + ")");
|
||||
if (dexFile.getPreserveSignedRegisters() && registerIsSigned) {
|
||||
out.writeSignedLeb128(registerNum);
|
||||
} else {
|
||||
out.writeUnsignedLeb128(registerNum);
|
||||
}
|
||||
if (nameIndex != -1) {
|
||||
Item nameItem = referencedItems[referencedItemsPosition++];
|
||||
assert nameItem instanceof StringIdItem;
|
||||
out.annotate("name: " + ((StringIdItem)nameItem).getStringValue());
|
||||
out.writeUnsignedLeb128(nameItem.getIndex() + 1);
|
||||
} else {
|
||||
out.annotate("name: ");
|
||||
out.writeByte(0);
|
||||
}
|
||||
if (typeIndex != -1) {
|
||||
Item typeItem = referencedItems[referencedItemsPosition++];
|
||||
assert typeItem instanceof TypeIdItem;
|
||||
out.annotate("type: " + ((TypeIdItem)typeItem).getTypeDescriptor());
|
||||
out.writeUnsignedLeb128(typeItem.getIndex() + 1);
|
||||
} else {
|
||||
out.annotate("type: ");
|
||||
out.writeByte(0);
|
||||
}
|
||||
if (signatureIndex != -1) {
|
||||
Item signatureItem = referencedItems[referencedItemsPosition++];
|
||||
assert signatureItem instanceof StringIdItem;
|
||||
out.annotate("signature: " + ((StringIdItem)signatureItem).getStringValue());
|
||||
out.writeUnsignedLeb128(signatureItem.getIndex() + 1);
|
||||
} else {
|
||||
out.annotate("signature: ");
|
||||
out.writeByte(0);
|
||||
}
|
||||
out.deindent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ProcessEndLocal(int startOffset, int length, int registerNum, boolean registerIsSigned) {
|
||||
out.annotate("DBG_END_LOCAL");
|
||||
out.writeByte(DebugOpcode.DBG_END_LOCAL.value);
|
||||
out.annotate("register_num: 0x" + Integer.toHexString(registerNum) + " (" + registerNum + ")");
|
||||
if (registerIsSigned) {
|
||||
out.writeSignedLeb128(registerNum);
|
||||
} else {
|
||||
out.writeUnsignedLeb128(registerNum);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ProcessRestartLocal(int startOffset, int length, int registerNum, boolean registerIsSigned) {
|
||||
out.annotate("DBG_RESTART_LOCAL");
|
||||
out.writeByte(DebugOpcode.DBG_RESTART_LOCAL.value);
|
||||
out.annotate("register_num: 0x" + Integer.toHexString(registerNum) + " (" + registerNum + ")");
|
||||
if (registerIsSigned) {
|
||||
out.writeSignedLeb128(registerNum);
|
||||
} else {
|
||||
out.writeUnsignedLeb128(registerNum);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ProcessSetPrologueEnd(int startOffset) {
|
||||
out.annotate("DBG_SET_PROLOGUE_END");
|
||||
out.writeByte(DebugOpcode.DBG_SET_PROLOGUE_END.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ProcessSetEpilogueBegin(int startOffset) {
|
||||
out.annotate("DBG_SET_EPILOGUE_BEGIN");
|
||||
out.writeByte(DebugOpcode.DBG_SET_EPILOGUE_BEGIN.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ProcessSetFile(int startOffset, int length, int nameIndex) {
|
||||
out.annotate("DBG_SET_FILE");
|
||||
out.writeByte(DebugOpcode.DBG_SET_FILE.value);
|
||||
if (nameIndex != -1) {
|
||||
Item sourceItem = referencedItems[referencedItemsPosition++];
|
||||
assert sourceItem instanceof StringIdItem;
|
||||
out.annotate("source_file: \"" + ((StringIdItem)sourceItem).getStringValue() + "\"");
|
||||
out.writeUnsignedLeb128(sourceItem.getIndex() + 1);
|
||||
} else {
|
||||
out.annotate("source_file: ");
|
||||
out.writeByte(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ProcessSpecialOpcode(int startOffset, int debugOpcode, int lineDiff, int addressDiff) {
|
||||
out.annotate("DBG_SPECIAL_OPCODE: line_diff=0x" + Integer.toHexString(lineDiff) + "(" +
|
||||
lineDiff +"),addressDiff=0x" + Integer.toHexString(addressDiff) + "(" + addressDiff +
|
||||
")");
|
||||
out.writeByte(debugOpcode);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public ItemType getItemType() {
|
||||
return ItemType.TYPE_DEBUG_INFO_ITEM;
|
||||
|
@ -526,6 +526,8 @@ public class DexFile
|
||||
out.annotate(0, " ");
|
||||
HeaderItem.writeTo(out);
|
||||
|
||||
out.annotate(0, " ");
|
||||
|
||||
int sectionsPosition = 0;
|
||||
Section[] sections;
|
||||
if (this.inplace) {
|
||||
@ -542,6 +544,12 @@ public class DexFile
|
||||
}
|
||||
|
||||
out.alignTo(MapItem.getItemType().ItemAlignment);
|
||||
|
||||
out.annotate(0, " ");
|
||||
out.annotate(0, "-----------------------------");
|
||||
out.annotate(0, "map item");
|
||||
out.annotate(0, "-----------------------------");
|
||||
out.annotate(0, " ");
|
||||
MapItem.writeTo(out);
|
||||
}
|
||||
|
||||
|
@ -79,9 +79,6 @@ public class EncodedArrayItem extends Item<EncodedArrayItem> {
|
||||
|
||||
/** {@inheritDoc} */
|
||||
protected void writeItem(AnnotatedOutput out) {
|
||||
if (out.annotates()) {
|
||||
out.annotate("encoded_array");
|
||||
}
|
||||
encodedArray.writeValue(out);
|
||||
}
|
||||
|
||||
|
@ -81,12 +81,21 @@ public class AnnotationEncodedSubValue extends EncodedValue {
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void writeValue(AnnotatedOutput out) {
|
||||
out.annotate("annotation_type: " + annotationType.getTypeDescriptor());
|
||||
out.writeUnsignedLeb128(annotationType.getIndex());
|
||||
out.annotate("element_count: 0x" + Integer.toHexString(names.length) + " (" + names.length + ")");
|
||||
out.writeUnsignedLeb128(names.length);
|
||||
|
||||
for (int i=0; i<names.length; i++) {
|
||||
out.annotate(0, "[" + i + "] annotation_element");
|
||||
out.indent();
|
||||
out.annotate("element_name: " + names[i].getStringValue());
|
||||
out.writeUnsignedLeb128(names[i].getIndex());
|
||||
out.annotate(0, "element_value:");
|
||||
out.indent();
|
||||
values[i].writeValue(out);
|
||||
out.deindent();
|
||||
out.deindent();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,9 @@ public class AnnotationEncodedValue extends AnnotationEncodedSubValue {
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void writeValue(AnnotatedOutput out) {
|
||||
if (out.annotates()) {
|
||||
out.annotate("value_type=" + ValueType.VALUE_ANNOTATION.name() + ",value_arg=0");
|
||||
}
|
||||
out.writeByte(ValueType.VALUE_ANNOTATION.value);
|
||||
super.writeValue(out);
|
||||
}
|
||||
|
@ -66,11 +66,24 @@ public class ArrayEncodedSubValue extends EncodedValue {
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void writeValue(AnnotatedOutput out) {
|
||||
if (out.annotates())
|
||||
{
|
||||
out.annotate("array_size: 0x" + Integer.toHexString(values.length) + " (" + values.length + ")");
|
||||
out.writeUnsignedLeb128(values.length);
|
||||
int index = 0;
|
||||
for (EncodedValue encodedValue: values) {
|
||||
out.annotate(0, "[" + index++ + "] array_element");
|
||||
out.indent();
|
||||
encodedValue.writeValue(out);
|
||||
out.deindent();
|
||||
}
|
||||
} else {
|
||||
out.writeUnsignedLeb128(values.length);
|
||||
for (EncodedValue encodedValue: values) {
|
||||
encodedValue.writeValue(out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public int placeValue(int offset) {
|
||||
|
@ -53,6 +53,9 @@ public class ArrayEncodedValue extends ArrayEncodedSubValue {
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void writeValue(AnnotatedOutput out) {
|
||||
if (out.annotates()) {
|
||||
out.annotate("value_type=" + ValueType.VALUE_ARRAY.name() + ",value_arg=0");
|
||||
}
|
||||
out.writeByte(ValueType.VALUE_ARRAY.value);
|
||||
super.writeValue(out);
|
||||
}
|
||||
|
@ -76,6 +76,9 @@ public class BooleanEncodedValue extends EncodedValue {
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void writeValue(AnnotatedOutput out) {
|
||||
if (out.annotates()) {
|
||||
out.annotate("value_type=" + ValueType.VALUE_BOOLEAN.name() + ",value=" + Boolean.toString(value));
|
||||
}
|
||||
out.writeByte(ValueType.VALUE_BOOLEAN.value | (value?1:0 << 5));
|
||||
}
|
||||
|
||||
|
@ -54,6 +54,10 @@ public class ByteEncodedValue extends EncodedValue {
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void writeValue(AnnotatedOutput out) {
|
||||
if (out.annotates()) {
|
||||
out.annotate(1, "value_type=" + ValueType.VALUE_BYTE.name() + ",value_arg=0");
|
||||
out.annotate(1, "value: 0x" + Integer.toHexString(value) + " (" + value + ")");
|
||||
}
|
||||
out.writeByte(ValueType.VALUE_BYTE.value);
|
||||
out.writeByte(value);
|
||||
}
|
||||
|
@ -57,6 +57,14 @@ public class CharEncodedValue extends EncodedValue {
|
||||
/** {@inheritDoc} */
|
||||
public void writeValue(AnnotatedOutput out) {
|
||||
byte[] bytes = EncodedValueUtils.encodeUnsignedIntegralValue(value);
|
||||
|
||||
if (out.annotates()) {
|
||||
out.annotate(1, "value_type=" + ValueType.VALUE_CHAR.name() + ",value_arg=" + (bytes.length - 1));
|
||||
char[] c = Character.toChars(value);
|
||||
assert c.length > 0;
|
||||
out.annotate(bytes.length, "value: 0x" + Integer.toHexString(value) + " '" + c[0] + "'");
|
||||
}
|
||||
|
||||
out.writeByte(ValueType.VALUE_CHAR.value | ((bytes.length - 1) << 5));
|
||||
out.write(bytes);
|
||||
}
|
||||
|
@ -58,6 +58,12 @@ public class DoubleEncodedValue extends EncodedValue {
|
||||
/** {@inheritDoc} */
|
||||
public void writeValue(AnnotatedOutput out) {
|
||||
byte[] bytes = EncodedValueUtils.encodeRightZeroExtendedValue(Double.doubleToRawLongBits(value));
|
||||
|
||||
if (out.annotates()) {
|
||||
out.annotate(1, "value_type=" + ValueType.VALUE_DOUBLE.name() + ",value_arg=" + (bytes.length - 1));
|
||||
out.annotate(bytes.length, "value: " + value);
|
||||
}
|
||||
|
||||
out.writeByte(ValueType.VALUE_DOUBLE.value | ((bytes.length - 1) << 5));
|
||||
out.write(bytes);
|
||||
}
|
||||
|
@ -61,6 +61,12 @@ public class EnumEncodedValue extends EncodedValue {
|
||||
/** {@inheritDoc} */
|
||||
public void writeValue(AnnotatedOutput out) {
|
||||
byte[] bytes = EncodedValueUtils.encodeUnsignedIntegralValue(value.getIndex());
|
||||
|
||||
if (out.annotates()) {
|
||||
out.annotate(1, "value_type=" + ValueType.VALUE_ENUM.name() + ",value_arg=" + (bytes.length - 1));
|
||||
out.annotate(bytes.length, "value: " + value.getFieldString());
|
||||
}
|
||||
|
||||
out.writeByte(ValueType.VALUE_ENUM.value | ((bytes.length - 1) << 5));
|
||||
out.write(bytes);
|
||||
}
|
||||
|
@ -61,6 +61,12 @@ public class FieldEncodedValue extends EncodedValue {
|
||||
/** {@inheritDoc} */
|
||||
public void writeValue(AnnotatedOutput out) {
|
||||
byte[] bytes = EncodedValueUtils.encodeUnsignedIntegralValue(value.getIndex());
|
||||
|
||||
if (out.annotates()) {
|
||||
out.annotate(1, "value_type=" + ValueType.VALUE_FIELD.name() + ",value_arg=" + (bytes.length - 1));
|
||||
out.annotate(bytes.length, "value: " + value.getFieldString());
|
||||
}
|
||||
|
||||
out.writeByte(ValueType.VALUE_FIELD.value | ((bytes.length - 1) << 5));
|
||||
out.write(bytes);
|
||||
}
|
||||
|
@ -58,6 +58,12 @@ public class FloatEncodedValue extends EncodedValue {
|
||||
/** {@inheritDoc} */
|
||||
public void writeValue(AnnotatedOutput out) {
|
||||
byte[] bytes = EncodedValueUtils.encodeRightZeroExtendedValue(((long)Float.floatToRawIntBits(value)) << 32);
|
||||
|
||||
if (out.annotates()) {
|
||||
out.annotate(1, "value_type=" + ValueType.VALUE_FLOAT.name() + ",value_arg=" + (bytes.length - 1));
|
||||
out.annotate(bytes.length, "value: " + value);
|
||||
}
|
||||
|
||||
out.writeByte(ValueType.VALUE_FLOAT.value | ((bytes.length - 1) << 5));
|
||||
out.write(bytes);
|
||||
}
|
||||
|
@ -57,6 +57,12 @@ public class IntEncodedValue extends EncodedValue {
|
||||
/** {@inheritDoc} */
|
||||
public void writeValue(AnnotatedOutput out) {
|
||||
byte[] bytes = EncodedValueUtils.encodeSignedIntegralValue(value);
|
||||
|
||||
if (out.annotates()) {
|
||||
out.annotate(1, "value_type=" + ValueType.VALUE_INT.name() + ",value_arg=" + (bytes.length - 1));
|
||||
out.annotate(bytes.length, "value: 0x" + Integer.toHexString(value) + " (" + value + ")");
|
||||
}
|
||||
|
||||
out.writeByte(ValueType.VALUE_INT.value | ((bytes.length - 1) << 5));
|
||||
out.write(bytes);
|
||||
}
|
||||
|
@ -57,6 +57,12 @@ public class LongEncodedValue extends EncodedValue {
|
||||
/** {@inheritDoc} */
|
||||
public void writeValue(AnnotatedOutput out) {
|
||||
byte[] bytes = EncodedValueUtils.encodeSignedIntegralValue(value);
|
||||
|
||||
if (out.annotates()) {
|
||||
out.annotate(1, "value_type=" + ValueType.VALUE_LONG.name() + ",value_arg=" + (bytes.length - 1));
|
||||
out.annotate(bytes.length, "value: 0x" + Long.toHexString(value) + " (" + value + ")");
|
||||
}
|
||||
|
||||
out.writeByte(ValueType.VALUE_LONG.value | ((bytes.length - 1) << 5));
|
||||
out.write(bytes);
|
||||
}
|
||||
|
@ -61,6 +61,12 @@ public class MethodEncodedValue extends EncodedValue {
|
||||
/** {@inheritDoc} */
|
||||
public void writeValue(AnnotatedOutput out) {
|
||||
byte[] bytes = EncodedValueUtils.encodeUnsignedIntegralValue(value.getIndex());
|
||||
|
||||
if (out.annotates()) {
|
||||
out.annotate(1, "value_type=" + ValueType.VALUE_METHOD.name() + ",value_arg=" + (bytes.length - 1));
|
||||
out.annotate(bytes.length, "value: " + value.getMethodString());
|
||||
}
|
||||
|
||||
out.writeByte(ValueType.VALUE_METHOD.value | ((bytes.length - 1) << 5));
|
||||
out.write(bytes);
|
||||
}
|
||||
|
@ -44,6 +44,9 @@ public class NullEncodedValue extends EncodedValue {
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void writeValue(AnnotatedOutput out) {
|
||||
if (out.annotates()) {
|
||||
out.annotate("value_type=" + ValueType.VALUE_NULL.name() + ",value_arg=0");
|
||||
}
|
||||
out.writeByte(ValueType.VALUE_NULL.value);
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,12 @@ public class ShortEncodedValue extends EncodedValue {
|
||||
/** {@inheritDoc} */
|
||||
public void writeValue(AnnotatedOutput out) {
|
||||
byte[] bytes = EncodedValueUtils.encodeSignedIntegralValue(value);
|
||||
|
||||
if (out.annotates()) {
|
||||
out.annotate(1, "value_type=" + ValueType.VALUE_SHORT.name() + ",value_arg=" + (bytes.length - 1));
|
||||
out.annotate(bytes.length, "value: 0x" + Integer.toHexString(value) + " (" + value + ")");
|
||||
}
|
||||
|
||||
out.writeByte(ValueType.VALUE_SHORT.value | ((bytes.length - 1) << 5));
|
||||
out.write(bytes);
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ package org.jf.dexlib.EncodedValue;
|
||||
import org.jf.dexlib.Util.Input;
|
||||
import org.jf.dexlib.Util.EncodedValueUtils;
|
||||
import org.jf.dexlib.Util.AnnotatedOutput;
|
||||
import org.jf.dexlib.Util.Utf8Utils;
|
||||
import org.jf.dexlib.StringIdItem;
|
||||
import org.jf.dexlib.DexFile;
|
||||
|
||||
@ -61,6 +62,12 @@ public class StringEncodedValue extends EncodedValue {
|
||||
/** {@inheritDoc} */
|
||||
public void writeValue(AnnotatedOutput out) {
|
||||
byte[] bytes = EncodedValueUtils.encodeUnsignedIntegralValue(value.getIndex());
|
||||
|
||||
if (out.annotates()) {
|
||||
out.annotate(1, "value_type=" + ValueType.VALUE_STRING.name() + ",value_arg=" + (bytes.length - 1));
|
||||
out.annotate(bytes.length, "value: \"" + Utf8Utils.escapeString(value.getStringValue()) + "\"");
|
||||
}
|
||||
|
||||
out.writeByte(ValueType.VALUE_STRING.value | ((bytes.length - 1) << 5));
|
||||
out.write(bytes);
|
||||
}
|
||||
|
@ -61,6 +61,12 @@ public class TypeEncodedValue extends EncodedValue {
|
||||
/** {@inheritDoc} */
|
||||
public void writeValue(AnnotatedOutput out) {
|
||||
byte[] bytes = EncodedValueUtils.encodeUnsignedIntegralValue(value.getIndex());
|
||||
|
||||
if (out.annotates()) {
|
||||
out.annotate(1, "value_type=" + ValueType.VALUE_TYPE.name() + ",value_arg=" + (bytes.length - 1));
|
||||
out.annotate(bytes.length, "value: " + value.getTypeDescriptor());
|
||||
}
|
||||
|
||||
out.writeByte(ValueType.VALUE_TYPE.value | ((bytes.length - 1) << 5));
|
||||
out.write(bytes);
|
||||
}
|
||||
|
@ -96,9 +96,9 @@ public class FieldIdItem extends Item<FieldIdItem> {
|
||||
/** {@inheritDoc} */
|
||||
protected void writeItem(AnnotatedOutput out) {
|
||||
if (out.annotates()) {
|
||||
out.annotate(2, classType.getConciseIdentity());
|
||||
out.annotate(2, fieldType.getConciseIdentity());
|
||||
out.annotate(4, fieldName.getConciseIdentity());
|
||||
out.annotate(2, "class_type: " + classType.getTypeDescriptor());
|
||||
out.annotate(2, "field_type: " + fieldType.getTypeDescriptor());
|
||||
out.annotate(4, "field_name: " + fieldName.getStringValue());
|
||||
}
|
||||
|
||||
out.writeShort(classType.getIndex());
|
||||
@ -157,6 +157,27 @@ public class FieldIdItem extends Item<FieldIdItem> {
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
String cachedFieldString = null;
|
||||
/**
|
||||
* @return a string formatted like LclassName;->fieldName:fieldType
|
||||
*/
|
||||
public String getFieldString() {
|
||||
if (cachedFieldString == null) {
|
||||
String typeDescriptor = classType.getTypeDescriptor();
|
||||
String fieldName = this.fieldName.getStringValue();
|
||||
String fieldType = this.fieldType.getTypeDescriptor();
|
||||
|
||||
StringBuffer sb = new StringBuffer(typeDescriptor.length() + fieldName.length() + fieldType.length() + 3);
|
||||
sb.append(typeDescriptor);
|
||||
sb.append("->");
|
||||
sb.append(fieldName);
|
||||
sb.append(":");
|
||||
sb.append(fieldType);
|
||||
cachedFieldString = sb.toString();
|
||||
}
|
||||
return cachedFieldString;
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate and cache the hashcode
|
||||
*/
|
||||
|
@ -86,21 +86,31 @@ public class MapItem extends Item<MapItem> {
|
||||
protected void writeItem(AnnotatedOutput out) {
|
||||
Assert.assertTrue(getOffset() > 0);
|
||||
|
||||
int index = 0;
|
||||
out.annotate(0, "[" + index++ + "]");
|
||||
out.indent();
|
||||
writeSectionInfo(out, ItemType.TYPE_HEADER_ITEM, 1, 0);
|
||||
out.deindent();
|
||||
|
||||
for (Section section: dexFile.getOrderedSections()) {
|
||||
out.annotate(0, "[" + index++ + "]");
|
||||
out.indent();
|
||||
writeSectionInfo(out, section.ItemType, section.getItems().size(), section.getOffset());
|
||||
out.deindent();
|
||||
}
|
||||
|
||||
out.annotate(0, "[" + index++ + "]");
|
||||
out.indent();
|
||||
writeSectionInfo(out, ItemType.TYPE_MAP_LIST, 1, dexFile.MapItem.getOffset());
|
||||
out.deindent();
|
||||
}
|
||||
|
||||
private void writeSectionInfo(AnnotatedOutput out, ItemType itemType, int sectionSize, int sectionOffset) {
|
||||
if (out.annotates()) {
|
||||
out.annotate(2, "ItemType: " + itemType);
|
||||
out.annotate(2, "item_type: " + itemType);
|
||||
out.annotate(2, "unused");
|
||||
out.annotate(4, "Section Size: " + sectionSize);
|
||||
out.annotate(4, "Section Offset: " + Hex.u4(sectionOffset));
|
||||
out.annotate(4, "section_size: 0x" + Integer.toHexString(sectionSize) + " (" + sectionSize + ")");
|
||||
out.annotate(4, "section_off: 0x" + Integer.toHexString(sectionOffset));
|
||||
}
|
||||
|
||||
out.writeShort(itemType.MapValue);
|
||||
|
@ -91,9 +91,9 @@ public class MethodIdItem extends Item<MethodIdItem> {
|
||||
/** {@inheritDoc} */
|
||||
protected void writeItem(AnnotatedOutput out) {
|
||||
if (out.annotates()) {
|
||||
out.annotate(2, classType.getConciseIdentity());
|
||||
out.annotate(2, methodPrototype.getConciseIdentity());
|
||||
out.annotate(4, methodName.getConciseIdentity());
|
||||
out.annotate(2, "class_type: " + classType.getTypeDescriptor());
|
||||
out.annotate(2, "method_prototype: " + methodPrototype.getPrototypeString());
|
||||
out.annotate(4, "method_name: " + methodName.getStringValue());
|
||||
}
|
||||
|
||||
out.writeShort(classType.getIndex());
|
||||
@ -132,8 +132,17 @@ public class MethodIdItem extends Item<MethodIdItem> {
|
||||
*/
|
||||
public String getMethodString() {
|
||||
if (cachedMethodString == null) {
|
||||
cachedMethodString = classType.getTypeDescriptor() + "->" + methodName.getStringValue() +
|
||||
methodPrototype.getPrototypeString();
|
||||
String classType = this.classType.getTypeDescriptor();
|
||||
String methodName = this.methodName.getStringValue();
|
||||
String prototypeString = methodPrototype.getPrototypeString();
|
||||
|
||||
StringBuilder sb = new StringBuilder(classType.length() + methodName.length() + prototypeString.length() +
|
||||
2);
|
||||
sb.append(classType);
|
||||
sb.append("->");
|
||||
sb.append(methodName);
|
||||
sb.append(prototypeString);
|
||||
cachedMethodString = sb.toString();
|
||||
}
|
||||
return cachedMethodString;
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ public class ProtoIdItem extends Item<ProtoIdItem> {
|
||||
if (parameters == null) {
|
||||
out.annotate(4, "parameters:");
|
||||
} else {
|
||||
out.annotate(4, "parameters: " + parameters.getTypeListString());
|
||||
out.annotate(4, "parameters: " + parameters.getTypeListString(""));
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,7 +145,7 @@ public class ProtoIdItem extends Item<ProtoIdItem> {
|
||||
if (cachedPrototypeString == null) {
|
||||
StringBuilder sb = new StringBuilder("(");
|
||||
if (parameters != null) {
|
||||
sb.append(parameters.getTypeListString());
|
||||
sb.append(parameters.getTypeListString(""));
|
||||
}
|
||||
sb.append(")");
|
||||
sb.append(returnType.getTypeDescriptor());
|
||||
|
@ -83,11 +83,14 @@ public class StringDataItem extends Item<StringDataItem> {
|
||||
protected void writeItem(AnnotatedOutput out) {
|
||||
byte[] encodedValue = Utf8Utils.stringToUtf8Bytes(stringValue);
|
||||
if (out.annotates()) {
|
||||
out.annotate(stringValue.length(), "string_size");
|
||||
out.annotate(encodedValue.length + 1, "string_data (" + Utf8Utils.escapeString(stringValue) + ")");
|
||||
}
|
||||
|
||||
out.annotate("string_size: 0x" + Integer.toHexString(stringValue.length()) + " (" + stringValue.length() +
|
||||
")");
|
||||
out.writeUnsignedLeb128(stringValue.length());
|
||||
|
||||
out.annotate(encodedValue.length + 1, "string_data: \"" + Utf8Utils.escapeString(stringValue) + "\"");
|
||||
} else {
|
||||
out.writeUnsignedLeb128(stringValue.length());
|
||||
}
|
||||
out.write(encodedValue);
|
||||
out.writeByte(0);
|
||||
}
|
||||
@ -99,7 +102,7 @@ public class StringDataItem extends Item<StringDataItem> {
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public String getConciseIdentity() {
|
||||
return "string_data_item: " + Utf8Utils.escapeString(getStringValue());
|
||||
return "string_data_item: \"" + Utf8Utils.escapeString(getStringValue()) + "\"";
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
|
@ -30,6 +30,7 @@ package org.jf.dexlib;
|
||||
|
||||
import org.jf.dexlib.Util.Input;
|
||||
import org.jf.dexlib.Util.AnnotatedOutput;
|
||||
import org.jf.dexlib.Util.ReadOnlyArrayList;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -91,21 +92,17 @@ public class TypeListItem extends Item<TypeListItem> {
|
||||
//yes, the code to write the item is duplicated. This eliminates the need to iterate over the list twice
|
||||
|
||||
if (out.annotates()) {
|
||||
out.annotate(4, "size: " + typeList.length);
|
||||
out.writeInt(typeList.length);
|
||||
out.annotate(4, "size: 0x" + Integer.toHexString(typeList.length) + " (" + typeList.length +")");
|
||||
|
||||
for (TypeIdItem typeIdItem: typeList) {
|
||||
out.annotate(2, typeIdItem.getConciseIdentity());
|
||||
out.writeShort(typeIdItem.getIndex());
|
||||
out.annotate(2, "type_id_item: " + typeIdItem.getTypeDescriptor());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
out.writeInt(typeList.length);
|
||||
for (TypeIdItem typeIdItem: typeList) {
|
||||
out.writeShort(typeIdItem.getIndex());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public ItemType getItemType() {
|
||||
@ -114,7 +111,7 @@ public class TypeListItem extends Item<TypeListItem> {
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public String getConciseIdentity() {
|
||||
return "type_list: " + getTypeListString();
|
||||
return "type_list: " + getTypeListString("");
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@ -154,22 +151,27 @@ public class TypeListItem extends Item<TypeListItem> {
|
||||
return wordCount;
|
||||
}
|
||||
|
||||
private String cachedTypeListString = null;
|
||||
/**
|
||||
* @return a string consisting of the type descriptors in this <code>TypeListItem</code>
|
||||
* that are directly concatenated together
|
||||
* that are separated by the given separator
|
||||
* @param separator the separator between each type
|
||||
*/
|
||||
public String getTypeListString() {
|
||||
|
||||
if (cachedTypeListString == null) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
public String getTypeListString(String separator) {
|
||||
int size = 0;
|
||||
for (TypeIdItem typeIdItem: typeList) {
|
||||
size += typeIdItem.getTypeDescriptor().length();
|
||||
size += separator.length();
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder(size);
|
||||
for (TypeIdItem typeIdItem: typeList) {
|
||||
sb.append(typeIdItem.getTypeDescriptor());
|
||||
sb.append(separator);
|
||||
}
|
||||
cachedTypeListString = sb.toString();
|
||||
if (typeList.length > 0) {
|
||||
sb.delete(sb.length() - separator.length(), sb.length());
|
||||
}
|
||||
return cachedTypeListString;
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -202,8 +204,8 @@ public class TypeListItem extends Item<TypeListItem> {
|
||||
/**
|
||||
* @return an array of the <code>TypeIdItems</code> in this <code>TypeListItem</code>
|
||||
*/
|
||||
public TypeIdItem[] getTypes() {
|
||||
return typeList.clone();
|
||||
public List<TypeIdItem> getTypes() {
|
||||
return new ReadOnlyArrayList<TypeIdItem>(typeList);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -78,39 +78,89 @@ public enum AccessFlags
|
||||
this.validForField = validForField;
|
||||
}
|
||||
|
||||
public static List<AccessFlags> getAccessFlagsForClass(int accessFlagValue) {
|
||||
ArrayList<AccessFlags> accessFlags = new ArrayList<AccessFlags>();
|
||||
|
||||
public static AccessFlags[] getAccessFlagsForClass(int accessFlagValue) {
|
||||
int size = 0;
|
||||
for (AccessFlags accessFlag: AccessFlags.values()) {
|
||||
if (accessFlag.validForClass && (accessFlagValue & accessFlag.value) != 0) {
|
||||
accessFlags.add(accessFlag);
|
||||
size++;
|
||||
}
|
||||
}
|
||||
|
||||
AccessFlags[] accessFlags = new AccessFlags[size];
|
||||
int accessFlagsPosition = 0;
|
||||
for (AccessFlags accessFlag: AccessFlags.values()) {
|
||||
if (accessFlag.validForClass && (accessFlagValue & accessFlag.value) != 0) {
|
||||
accessFlags[accessFlagsPosition++] = accessFlag;
|
||||
}
|
||||
}
|
||||
return accessFlags;
|
||||
}
|
||||
|
||||
public static List<AccessFlags> getAccessFlagsForMethod(int accessFlagValue) {
|
||||
ArrayList<AccessFlags> accessFlags = new ArrayList<AccessFlags>();
|
||||
private static String formatAccessFlags(AccessFlags[] accessFlags) {
|
||||
int size = 0;
|
||||
for (AccessFlags accessFlag: accessFlags) {
|
||||
size += accessFlag.toString().length() + 1;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder(size);
|
||||
for (AccessFlags accessFlag: accessFlags) {
|
||||
sb.append(accessFlag.toString());
|
||||
sb.append(" ");
|
||||
}
|
||||
if (accessFlags.length > 0) {
|
||||
sb.delete(sb.length() - 1, sb.length());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String formatAccessFlagsForClass(int accessFlagValue) {
|
||||
return formatAccessFlags(getAccessFlagsForClass(accessFlagValue));
|
||||
}
|
||||
|
||||
public static AccessFlags[] getAccessFlagsForMethod(int accessFlagValue) {
|
||||
int size = 0;
|
||||
for (AccessFlags accessFlag: AccessFlags.values()) {
|
||||
if (accessFlag.validForMethod && (accessFlagValue & accessFlag.value) != 0) {
|
||||
accessFlags.add(accessFlag);
|
||||
size++;
|
||||
}
|
||||
}
|
||||
|
||||
AccessFlags[] accessFlags = new AccessFlags[size];
|
||||
int accessFlagsPosition = 0;
|
||||
for (AccessFlags accessFlag: AccessFlags.values()) {
|
||||
if (accessFlag.validForMethod && (accessFlagValue & accessFlag.value) != 0) {
|
||||
accessFlags[accessFlagsPosition++] = accessFlag;
|
||||
}
|
||||
}
|
||||
return accessFlags;
|
||||
}
|
||||
|
||||
public static List<AccessFlags> getAccessFlagsForField(int accessFlagValue) {
|
||||
ArrayList<AccessFlags> accessFlags = new ArrayList<AccessFlags>();
|
||||
public static String formatAccessFlagsForMethod(int accessFlagValue) {
|
||||
return formatAccessFlags(getAccessFlagsForMethod(accessFlagValue));
|
||||
}
|
||||
|
||||
public static AccessFlags[] getAccessFlagsForField(int accessFlagValue) {
|
||||
int size = 0;
|
||||
for (AccessFlags accessFlag: AccessFlags.values()) {
|
||||
if (accessFlag.validForField && (accessFlagValue & accessFlag.value) != 0) {
|
||||
accessFlags.add(accessFlag);
|
||||
size++;
|
||||
}
|
||||
}
|
||||
|
||||
AccessFlags[] accessFlags = new AccessFlags[size];
|
||||
int accessFlagsPosition = 0;
|
||||
for (AccessFlags accessFlag: AccessFlags.values()) {
|
||||
if (accessFlag.validForField && (accessFlagValue & accessFlag.value) != 0) {
|
||||
accessFlags[accessFlagsPosition++] = accessFlag;
|
||||
}
|
||||
}
|
||||
return accessFlags;
|
||||
}
|
||||
|
||||
public static String formatAccessFlagsForField(int accessFlagValue) {
|
||||
return formatAccessFlags(getAccessFlagsForField(accessFlagValue));
|
||||
}
|
||||
|
||||
public static AccessFlags getAccessFlag(String accessFlag) {
|
||||
return accessFlagsByName.get(accessFlag);
|
||||
}
|
||||
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.jf.dexlib.Util;
|
||||
|
||||
import java.util.AbstractList;
|
||||
import java.util.RandomAccess;
|
||||
|
||||
public class ReadOnlyArrayList<T> extends AbstractList<T> implements RandomAccess {
|
||||
private final T[] arr;
|
||||
|
||||
public ReadOnlyArrayList(T[] arr) {
|
||||
this.arr = arr;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return arr.length;
|
||||
}
|
||||
|
||||
public T get(int i) {
|
||||
return arr[i];
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user