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:
JesusFreke@JesusFreke.com 2009-08-21 02:50:07 +00:00
parent d9dd571427
commit 4d68e05fb5
38 changed files with 697 additions and 135 deletions

View File

@ -177,25 +177,49 @@ public class AnnotationDirectoryItem extends Item<AnnotationDirectoryItem> {
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) { protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) { if (out.annotates()) {
out.annotate(4, "class_annotations_off"); if (!isInternable() && parent != null) {
out.annotate(4, "annotated_fields_size"); out.annotate(0, parent.getClassType().getTypeDescriptor());
out.annotate(4, "annotated_methods_size"); }
out.annotate(4, "annotated_parameters_size"); 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++) { for (int i=0; i<fieldAnnotations.length; i++) {
out.annotate(4, "field_idx"); out.annotate(0, "[" + index++ + "] field_annotation");
out.annotate(4, "annotations_off");
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++) { for (int i=0; i<methodAnnotations.length; i++) {
out.annotate(4, "method_idx"); out.annotate(0, "[" + index++ + "] method_annotation");
out.annotate(4, "annotations_off"); 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++) { for (int i=0; i<parameterAnnotations.length; i++) {
out.annotate(4, "method_idx"); out.annotate(0, "[" + index++ + "] parameter_annotation");
out.annotate(4, "annotations_off"); out.indent();
out.annotate(4, "method: " + parameterAnnotationMethods[i].getMethodString());
out.annotate(4, "annotations_off: 0x" + Integer.toHexString(parameterAnnotations[i].getOffset()));
} }
} }

View File

@ -88,9 +88,8 @@ public class AnnotationItem extends Item<AnnotationItem> {
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) { protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) { if (out.annotates()) {
out.annotate("visibility"); out.annotate("visibility: " + visibility.name());
out.writeByte(visibility.value); out.writeByte(visibility.value);
out.annotate("annotation");
annotationValue.writeValue(out); annotationValue.writeValue(out);
}else { }else {
out.writeByte(visibility.value); out.writeByte(visibility.value);

View File

@ -84,9 +84,10 @@ public class AnnotationSetItem extends Item<AnnotationSetItem> {
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) { protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) { if (out.annotates()) {
out.annotate(4, "size"); out.annotate(4, "size: 0x" + Integer.toHexString(annotations.length) + " (" + annotations.length + ")");
for (int i=0; i<annotations.length; i++) { for (AnnotationItem annotationItem: annotations) {
out.annotate(4, "annotation_off"); out.annotate(4, "annotation_off: 0x" + Integer.toHexString(annotationItem.getOffset()) + " - " +
annotationItem.getEncodedAnnotation().annotationType.getTypeDescriptor());
} }
} }
out.writeInt(annotations.length); out.writeInt(annotations.length);

View File

@ -85,9 +85,10 @@ public class AnnotationSetRefList extends Item<AnnotationSetRefList> {
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) { protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) { if (out.annotates()) {
out.annotate(4, "size"); out.annotate(4, "size: 0x" + Integer.toHexString(annotationSets.length) + " (" + annotationSets.length +
")");
for (AnnotationSetItem annotationSetItem: annotationSets) { 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); out.writeInt(annotationSets.length);

View File

@ -147,36 +147,56 @@ public class ClassDataItem extends Item<ClassDataItem> {
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) { protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) { 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.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.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.writeUnsignedLeb128(directMethods.length);
out.annotate("virtual_methods_size"); out.annotate("virtual_methods_size: 0x" + Integer.toHexString(virtualMethods.length) + " (" +
virtualMethods.length + ")");
out.writeUnsignedLeb128(virtualMethods.length); out.writeUnsignedLeb128(virtualMethods.length);
int index = 0;
EncodedField previousEncodedField = null; EncodedField previousEncodedField = null;
for (EncodedField encodedField: staticFields) { for (EncodedField encodedField: staticFields) {
out.annotate("[" + index++ + "] static_field");
out.indent();
encodedField.writeTo(out, previousEncodedField); encodedField.writeTo(out, previousEncodedField);
out.deindent();
previousEncodedField = encodedField; previousEncodedField = encodedField;
} }
index = 0;
previousEncodedField = null; previousEncodedField = null;
for (EncodedField encodedField: instanceFields) { for (EncodedField encodedField: instanceFields) {
out.annotate("[" + index++ + "] instance_field");
out.indent();
encodedField.writeTo(out, previousEncodedField); encodedField.writeTo(out, previousEncodedField);
out.deindent();
previousEncodedField = encodedField; previousEncodedField = encodedField;
} }
index = 0;
EncodedMethod previousEncodedMethod = null; EncodedMethod previousEncodedMethod = null;
for (EncodedMethod encodedMethod: directMethods) { for (EncodedMethod encodedMethod: directMethods) {
out.annotate("[" + index++ + "] direct_method");
out.indent();
encodedMethod.writeTo(out, previousEncodedMethod); encodedMethod.writeTo(out, previousEncodedMethod);
out.deindent();
previousEncodedMethod = encodedMethod; previousEncodedMethod = encodedMethod;
} }
index = 0;
previousEncodedMethod = null; previousEncodedMethod = null;
for (EncodedMethod encodedMethod: virtualMethods) { for (EncodedMethod encodedMethod: virtualMethods) {
out.annotate("[" + index++ + "] virtual_method");
out.indent();
encodedMethod.writeTo(out, previousEncodedMethod); encodedMethod.writeTo(out, previousEncodedMethod);
out.deindent();
previousEncodedMethod = encodedMethod; previousEncodedMethod = encodedMethod;
} }
} else { } else {
@ -315,9 +335,9 @@ public class ClassDataItem extends Item<ClassDataItem> {
int previousIndex = previousEncodedField==null?0:previousEncodedField.field.getIndex(); int previousIndex = previousEncodedField==null?0:previousEncodedField.field.getIndex();
if (out.annotates()) { if (out.annotates()) {
out.annotate("field_idx_diff"); out.annotate("field: " + field.getFieldString());
out.writeUnsignedLeb128(field.getIndex() - previousIndex); out.writeUnsignedLeb128(field.getIndex() - previousIndex);
out.annotate("access_flags"); out.annotate("access_flags: " + AccessFlags.formatAccessFlagsForField(accessFlags));
out.writeUnsignedLeb128(accessFlags); out.writeUnsignedLeb128(accessFlags);
}else { }else {
out.writeUnsignedLeb128(field.getIndex() - previousIndex); out.writeUnsignedLeb128(field.getIndex() - previousIndex);
@ -422,12 +442,17 @@ public class ClassDataItem extends Item<ClassDataItem> {
int previousIndex = previousEncodedMethod==null?0:previousEncodedMethod.method.getIndex(); int previousIndex = previousEncodedMethod==null?0:previousEncodedMethod.method.getIndex();
if (out.annotates()) { if (out.annotates()) {
out.annotate("method_idx_diff"); out.annotate("method: " + method.getMethodString());
out.writeUnsignedLeb128(method.getIndex() - previousIndex); out.writeUnsignedLeb128(method.getIndex() - previousIndex);
out.annotate("access_flags"); out.annotate("access_flags: " + AccessFlags.formatAccessFlagsForMethod(accessFlags));
out.writeUnsignedLeb128(accessFlags); out.writeUnsignedLeb128(accessFlags);
out.annotate("code_off"); if (codeItem != null) {
out.writeUnsignedLeb128(codeItem==null?0:codeItem.getOffset()); out.annotate("code_off: 0x" + codeItem.getOffset());
out.writeUnsignedLeb128(codeItem.getOffset());
} else {
out.annotate("code_off: 0x0");
out.writeUnsignedLeb128(0);
}
}else { }else {
out.writeUnsignedLeb128(method.getIndex() - previousIndex); out.writeUnsignedLeb128(method.getIndex() - previousIndex);
out.writeUnsignedLeb128(accessFlags); out.writeUnsignedLeb128(accessFlags);

View File

@ -30,6 +30,7 @@ package org.jf.dexlib;
import org.jf.dexlib.Util.Input; import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput; import org.jf.dexlib.Util.AnnotatedOutput;
import org.jf.dexlib.Util.AccessFlags;
import java.util.*; import java.util.*;
@ -139,14 +140,18 @@ public class ClassDefItem extends Item<ClassDefItem> {
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) { protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) { if (out.annotates()) {
out.annotate(4, "class_idx"); out.annotate(4, "class_type: " + classType.getTypeDescriptor());
out.annotate(4, "access_flags"); out.annotate(4, "access_flags: " + AccessFlags.formatAccessFlagsForClass(accessFlags));
out.annotate(4, "superclass_idx"); out.annotate(4, "superclass_type: " + (superType==null?"":superType.getTypeDescriptor()));
out.annotate(4, "interfaces_off"); out.annotate(4, "interfaces: " +
out.annotate(4, "source_file_idx"); (implementedInterfaces==null?"":implementedInterfaces.getTypeListString(" ")));
out.annotate(4, "annotations_off"); out.annotate(4, "source_file: " + (sourceFile==null?"":sourceFile.getStringValue()));
out.annotate(4, "class_data_off"); out.annotate(4, "annotations_off: " +
out.annotate(4, "static_values_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(classType.getIndex());
out.writeInt(accessFlags); out.writeInt(accessFlags);

View File

@ -186,33 +186,46 @@ public class CodeItem extends Item<CodeItem> {
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void writeItem(final AnnotatedOutput out) { protected void writeItem(final AnnotatedOutput out) {
if (out.annotates()) { if (out.annotates()) {
out.annotate(2, "registers_size"); out.annotate(0, parent.method.getMethodString());
out.annotate(2, "ins_size"); out.annotate(2, "registers_size: 0x" + Integer.toHexString(registerCount) + " (" + registerCount + ")");
out.annotate(2, "outs_size"); out.annotate(2, "ins_size: 0x" + Integer.toHexString(inWords) + " (" + inWords + ")");
out.annotate(2, "tries_size"); out.annotate(2, "outs_size: 0x" + Integer.toHexString(outWords) + " (" + outWords + ")");
out.annotate(4, "debug_info_off"); int triesLength = tries==null?0:tries.length;
out.annotate(4, "insns_size"); 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, InstructionIterator.IterateInstructions(encodedInstructions,
new InstructionIterator.ProcessRawInstructionDelegate() { new InstructionIterator.ProcessRawInstructionDelegate() {
public void ProcessNormalInstruction(Opcode opcode, int index) { 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) { 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) { 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) { 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) { public void ProcessFillArrayDataInstruction(int index, int elementWidth, int elementCount,
out.annotate(instructionLength, "fill_array_data instruction"); int instructionLength) {
out.annotate(instructionLength, "[0x" + Integer.toHexString(index/2) + "] " +
"fill_array_data instruction");
} }
}); });
if (tries != null && (tries.length % 2 == 1)) { if (tries != null && (tries.length % 2 == 1)) {
@ -237,6 +250,32 @@ public class CodeItem extends Item<CodeItem> {
InstructionWriter.writeInstructions(encodedInstructions, referencedItems, out); InstructionWriter.writeInstructions(encodedInstructions, referencedItems, out);
if (tries != null && tries.length > 0) { 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) { if ((encodedInstructions.length % 4) != 0) {
out.writeShort(0); out.writeShort(0);
} }
@ -252,6 +291,7 @@ public class CodeItem extends Item<CodeItem> {
} }
} }
} }
}
/** {@inheritDoc} */ /** {@inheritDoc} */
public ItemType getItemType() { public ItemType getItemType() {
@ -373,9 +413,10 @@ public class CodeItem extends Item<CodeItem> {
*/ */
private void writeTo(AnnotatedOutput out) { private void writeTo(AnnotatedOutput out) {
if (out.annotates()) { if (out.annotates()) {
out.annotate(4, "start_addr"); out.annotate(4, "start_addr: 0x" + Integer.toHexString(startAddress));
out.annotate(2, "insn_count"); out.annotate(2, "insn_count: 0x" + Integer.toHexString(instructionCount) + " (" + instructionCount +
out.annotate(2, "handler_off"); ")");
out.annotate(2, "handler_off: 0x" + Integer.toHexString(encodedCatchHandler.getOffsetInList()));
} }
out.writeInt(startAddress); out.writeInt(startAddress);
@ -476,7 +517,7 @@ public class CodeItem extends Item<CodeItem> {
*/ */
private void writeTo(AnnotatedOutput out) { private void writeTo(AnnotatedOutput out) {
if (out.annotates()) { if (out.annotates()) {
out.annotate("size"); out.annotate("size: 0x" + Integer.toHexString(handlers.length) + " (" + handlers.length + ")");
int size = handlers.length; int size = handlers.length;
if (catchAllHandlerAddress < 0) { if (catchAllHandlerAddress < 0) {
@ -484,12 +525,16 @@ public class CodeItem extends Item<CodeItem> {
} }
out.writeSignedLeb128(size); out.writeSignedLeb128(size);
int index = 0;
for (EncodedTypeAddrPair handler: handlers) { for (EncodedTypeAddrPair handler: handlers) {
out.annotate(0, "[" + index++ + "] encoded_type_addr_pair");
out.indent();
handler.writeTo(out); handler.writeTo(out);
out.deindent();
} }
if (catchAllHandlerAddress > -1) { if (catchAllHandlerAddress > -1) {
out.annotate("catch_all_addr"); out.annotate("catch_all_addr: 0x" + Integer.toHexString(catchAllHandlerAddress));
out.writeUnsignedLeb128(catchAllHandlerAddress); out.writeUnsignedLeb128(catchAllHandlerAddress);
} }
} else { } else {
@ -556,10 +601,10 @@ public class CodeItem extends Item<CodeItem> {
*/ */
private void writeTo(AnnotatedOutput out) { private void writeTo(AnnotatedOutput out) {
if (out.annotates()) { if (out.annotates()) {
out.annotate("type_idx"); out.annotate("exception_type: " + exceptionType.getTypeDescriptor());
out.writeUnsignedLeb128(exceptionType.getIndex()); out.writeUnsignedLeb128(exceptionType.getIndex());
out.annotate("addr"); out.annotate("handler_addr: 0x" + Integer.toHexString(handlerAddress));
out.writeUnsignedLeb128(handlerAddress); out.writeUnsignedLeb128(handlerAddress);
} else { } else {
out.writeUnsignedLeb128(exceptionType.getIndex()); out.writeUnsignedLeb128(exceptionType.getIndex());

View File

@ -266,15 +266,15 @@ public class DebugInstructionIterator {
{ {
//TODO: add javadocs //TODO: add javadocs
public void ProcessEndSequence(int startOffset) { public void ProcessEndSequence(int startOffset) {
ProcessStaticOpcode(startOffset, 1); ProcessStaticOpcode(DebugOpcode.DBG_END_SEQUENCE, startOffset, 1);
} }
public void ProcessAdvancePC(int startOffset, int length, int addressDiff) { 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) { 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, 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) { 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) { 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) { public void ProcessSetPrologueEnd(int startOffset) {
ProcessStaticOpcode(startOffset, 1); ProcessStaticOpcode(DebugOpcode.DBG_SET_PROLOGUE_END, startOffset, 1);
} }
public void ProcessSetEpilogueBegin(int startOffset) { 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 ProcessSetFile(int startOffset, int length, int nameIndex) {
} }
public void ProcessSpecialOpcode(int startOffset, int debugOpcode, int lineDiff, int addressDiff) { 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) {
} }
} }

View File

@ -37,7 +37,7 @@ public enum DebugOpcode {
DBG_END_LOCAL((byte)0x05), DBG_END_LOCAL((byte)0x05),
DBG_RESTART_LOCAL((byte)0x06), DBG_RESTART_LOCAL((byte)0x06),
DBG_SET_PROLOGUE_END((byte)0x07), DBG_SET_PROLOGUE_END((byte)0x07),
DBG_SET_EPILOGUE_END((byte)0x08), DBG_SET_EPILOGUE_BEGIN((byte)0x08),
DBG_SET_FILE((byte)0x09), DBG_SET_FILE((byte)0x09),
DBG_SPECIAL_OPCODE((byte)0x0A); DBG_SPECIAL_OPCODE((byte)0x0A);

View File

@ -187,7 +187,7 @@ public class DebugInfoItem extends Item<DebugInfoItem> {
private int referencedItemsPosition = 0; private int referencedItemsPosition = 0;
@Override @Override
public void ProcessStaticOpcode(int startOffset, int length) { public void ProcessStaticOpcode(DebugOpcode opcode, int startOffset, int length) {
this.length+=length; this.length+=length;
} }
@ -261,6 +261,19 @@ public class DebugInfoItem extends Item<DebugInfoItem> {
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void writeItem(final AnnotatedOutput out) { 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(lineStart);
out.writeUnsignedLeb128(parameterNames.length); out.writeUnsignedLeb128(parameterNames.length);
for (StringIdItem parameterName: parameterNames) { for (StringIdItem parameterName: parameterNames) {
@ -278,7 +291,7 @@ public class DebugInfoItem extends Item<DebugInfoItem> {
private int referencedItemsPosition = 0; private int referencedItemsPosition = 0;
@Override @Override
public void ProcessStaticOpcode(int startOffset, int length) { public void ProcessStaticOpcode(DebugOpcode opcode, int startOffset, int length) {
out.write(encodedDebugInfo, startOffset, 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} */ /** {@inheritDoc} */
public ItemType getItemType() { public ItemType getItemType() {
return ItemType.TYPE_DEBUG_INFO_ITEM; return ItemType.TYPE_DEBUG_INFO_ITEM;

View File

@ -526,6 +526,8 @@ public class DexFile
out.annotate(0, " "); out.annotate(0, " ");
HeaderItem.writeTo(out); HeaderItem.writeTo(out);
out.annotate(0, " ");
int sectionsPosition = 0; int sectionsPosition = 0;
Section[] sections; Section[] sections;
if (this.inplace) { if (this.inplace) {
@ -542,6 +544,12 @@ public class DexFile
} }
out.alignTo(MapItem.getItemType().ItemAlignment); 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); MapItem.writeTo(out);
} }

View File

@ -79,9 +79,6 @@ public class EncodedArrayItem extends Item<EncodedArrayItem> {
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) { protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
out.annotate("encoded_array");
}
encodedArray.writeValue(out); encodedArray.writeValue(out);
} }

View File

@ -81,12 +81,21 @@ public class AnnotationEncodedSubValue extends EncodedValue {
/** {@inheritDoc} */ /** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) { public void writeValue(AnnotatedOutput out) {
out.annotate("annotation_type: " + annotationType.getTypeDescriptor());
out.writeUnsignedLeb128(annotationType.getIndex()); out.writeUnsignedLeb128(annotationType.getIndex());
out.annotate("element_count: 0x" + Integer.toHexString(names.length) + " (" + names.length + ")");
out.writeUnsignedLeb128(names.length); out.writeUnsignedLeb128(names.length);
for (int i=0; i<names.length; i++) { 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.writeUnsignedLeb128(names[i].getIndex());
out.annotate(0, "element_value:");
out.indent();
values[i].writeValue(out); values[i].writeValue(out);
out.deindent();
out.deindent();
} }
} }

View File

@ -58,6 +58,9 @@ public class AnnotationEncodedValue extends AnnotationEncodedSubValue {
/** {@inheritDoc} */ /** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) { 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); out.writeByte(ValueType.VALUE_ANNOTATION.value);
super.writeValue(out); super.writeValue(out);
} }

View File

@ -66,11 +66,24 @@ public class ArrayEncodedSubValue extends EncodedValue {
/** {@inheritDoc} */ /** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) { 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); out.writeUnsignedLeb128(values.length);
for (EncodedValue encodedValue: values) { for (EncodedValue encodedValue: values) {
encodedValue.writeValue(out); encodedValue.writeValue(out);
} }
} }
}
/** {@inheritDoc} */ /** {@inheritDoc} */
public int placeValue(int offset) { public int placeValue(int offset) {

View File

@ -53,6 +53,9 @@ public class ArrayEncodedValue extends ArrayEncodedSubValue {
/** {@inheritDoc} */ /** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) { 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); out.writeByte(ValueType.VALUE_ARRAY.value);
super.writeValue(out); super.writeValue(out);
} }

View File

@ -76,6 +76,9 @@ public class BooleanEncodedValue extends EncodedValue {
/** {@inheritDoc} */ /** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) { 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)); out.writeByte(ValueType.VALUE_BOOLEAN.value | (value?1:0 << 5));
} }

View File

@ -54,6 +54,10 @@ public class ByteEncodedValue extends EncodedValue {
/** {@inheritDoc} */ /** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) { 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(ValueType.VALUE_BYTE.value);
out.writeByte(value); out.writeByte(value);
} }

View File

@ -57,6 +57,14 @@ public class CharEncodedValue extends EncodedValue {
/** {@inheritDoc} */ /** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) { public void writeValue(AnnotatedOutput out) {
byte[] bytes = EncodedValueUtils.encodeUnsignedIntegralValue(value); 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.writeByte(ValueType.VALUE_CHAR.value | ((bytes.length - 1) << 5));
out.write(bytes); out.write(bytes);
} }

View File

@ -58,6 +58,12 @@ public class DoubleEncodedValue extends EncodedValue {
/** {@inheritDoc} */ /** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) { public void writeValue(AnnotatedOutput out) {
byte[] bytes = EncodedValueUtils.encodeRightZeroExtendedValue(Double.doubleToRawLongBits(value)); 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.writeByte(ValueType.VALUE_DOUBLE.value | ((bytes.length - 1) << 5));
out.write(bytes); out.write(bytes);
} }

View File

@ -61,6 +61,12 @@ public class EnumEncodedValue extends EncodedValue {
/** {@inheritDoc} */ /** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) { public void writeValue(AnnotatedOutput out) {
byte[] bytes = EncodedValueUtils.encodeUnsignedIntegralValue(value.getIndex()); 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.writeByte(ValueType.VALUE_ENUM.value | ((bytes.length - 1) << 5));
out.write(bytes); out.write(bytes);
} }

View File

@ -61,6 +61,12 @@ public class FieldEncodedValue extends EncodedValue {
/** {@inheritDoc} */ /** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) { public void writeValue(AnnotatedOutput out) {
byte[] bytes = EncodedValueUtils.encodeUnsignedIntegralValue(value.getIndex()); 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.writeByte(ValueType.VALUE_FIELD.value | ((bytes.length - 1) << 5));
out.write(bytes); out.write(bytes);
} }

View File

@ -58,6 +58,12 @@ public class FloatEncodedValue extends EncodedValue {
/** {@inheritDoc} */ /** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) { public void writeValue(AnnotatedOutput out) {
byte[] bytes = EncodedValueUtils.encodeRightZeroExtendedValue(((long)Float.floatToRawIntBits(value)) << 32); 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.writeByte(ValueType.VALUE_FLOAT.value | ((bytes.length - 1) << 5));
out.write(bytes); out.write(bytes);
} }

View File

@ -57,6 +57,12 @@ public class IntEncodedValue extends EncodedValue {
/** {@inheritDoc} */ /** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) { public void writeValue(AnnotatedOutput out) {
byte[] bytes = EncodedValueUtils.encodeSignedIntegralValue(value); 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.writeByte(ValueType.VALUE_INT.value | ((bytes.length - 1) << 5));
out.write(bytes); out.write(bytes);
} }

View File

@ -57,6 +57,12 @@ public class LongEncodedValue extends EncodedValue {
/** {@inheritDoc} */ /** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) { public void writeValue(AnnotatedOutput out) {
byte[] bytes = EncodedValueUtils.encodeSignedIntegralValue(value); 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.writeByte(ValueType.VALUE_LONG.value | ((bytes.length - 1) << 5));
out.write(bytes); out.write(bytes);
} }

View File

@ -61,6 +61,12 @@ public class MethodEncodedValue extends EncodedValue {
/** {@inheritDoc} */ /** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) { public void writeValue(AnnotatedOutput out) {
byte[] bytes = EncodedValueUtils.encodeUnsignedIntegralValue(value.getIndex()); 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.writeByte(ValueType.VALUE_METHOD.value | ((bytes.length - 1) << 5));
out.write(bytes); out.write(bytes);
} }

View File

@ -44,6 +44,9 @@ public class NullEncodedValue extends EncodedValue {
/** {@inheritDoc} */ /** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) { 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); out.writeByte(ValueType.VALUE_NULL.value);
} }

View File

@ -57,6 +57,12 @@ public class ShortEncodedValue extends EncodedValue {
/** {@inheritDoc} */ /** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) { public void writeValue(AnnotatedOutput out) {
byte[] bytes = EncodedValueUtils.encodeSignedIntegralValue(value); 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.writeByte(ValueType.VALUE_SHORT.value | ((bytes.length - 1) << 5));
out.write(bytes); out.write(bytes);
} }

View File

@ -31,6 +31,7 @@ package org.jf.dexlib.EncodedValue;
import org.jf.dexlib.Util.Input; import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.EncodedValueUtils; import org.jf.dexlib.Util.EncodedValueUtils;
import org.jf.dexlib.Util.AnnotatedOutput; import org.jf.dexlib.Util.AnnotatedOutput;
import org.jf.dexlib.Util.Utf8Utils;
import org.jf.dexlib.StringIdItem; import org.jf.dexlib.StringIdItem;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
@ -61,6 +62,12 @@ public class StringEncodedValue extends EncodedValue {
/** {@inheritDoc} */ /** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) { public void writeValue(AnnotatedOutput out) {
byte[] bytes = EncodedValueUtils.encodeUnsignedIntegralValue(value.getIndex()); 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.writeByte(ValueType.VALUE_STRING.value | ((bytes.length - 1) << 5));
out.write(bytes); out.write(bytes);
} }

View File

@ -61,6 +61,12 @@ public class TypeEncodedValue extends EncodedValue {
/** {@inheritDoc} */ /** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) { public void writeValue(AnnotatedOutput out) {
byte[] bytes = EncodedValueUtils.encodeUnsignedIntegralValue(value.getIndex()); 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.writeByte(ValueType.VALUE_TYPE.value | ((bytes.length - 1) << 5));
out.write(bytes); out.write(bytes);
} }

View File

@ -96,9 +96,9 @@ public class FieldIdItem extends Item<FieldIdItem> {
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) { protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) { if (out.annotates()) {
out.annotate(2, classType.getConciseIdentity()); out.annotate(2, "class_type: " + classType.getTypeDescriptor());
out.annotate(2, fieldType.getConciseIdentity()); out.annotate(2, "field_type: " + fieldType.getTypeDescriptor());
out.annotate(4, fieldName.getConciseIdentity()); out.annotate(4, "field_name: " + fieldName.getStringValue());
} }
out.writeShort(classType.getIndex()); out.writeShort(classType.getIndex());
@ -157,6 +157,27 @@ public class FieldIdItem extends Item<FieldIdItem> {
return fieldName; 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 * calculate and cache the hashcode
*/ */

View File

@ -86,21 +86,31 @@ public class MapItem extends Item<MapItem> {
protected void writeItem(AnnotatedOutput out) { protected void writeItem(AnnotatedOutput out) {
Assert.assertTrue(getOffset() > 0); Assert.assertTrue(getOffset() > 0);
int index = 0;
out.annotate(0, "[" + index++ + "]");
out.indent();
writeSectionInfo(out, ItemType.TYPE_HEADER_ITEM, 1, 0); writeSectionInfo(out, ItemType.TYPE_HEADER_ITEM, 1, 0);
out.deindent();
for (Section section: dexFile.getOrderedSections()) { for (Section section: dexFile.getOrderedSections()) {
out.annotate(0, "[" + index++ + "]");
out.indent();
writeSectionInfo(out, section.ItemType, section.getItems().size(), section.getOffset()); 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()); writeSectionInfo(out, ItemType.TYPE_MAP_LIST, 1, dexFile.MapItem.getOffset());
out.deindent();
} }
private void writeSectionInfo(AnnotatedOutput out, ItemType itemType, int sectionSize, int sectionOffset) { private void writeSectionInfo(AnnotatedOutput out, ItemType itemType, int sectionSize, int sectionOffset) {
if (out.annotates()) { if (out.annotates()) {
out.annotate(2, "ItemType: " + itemType); out.annotate(2, "item_type: " + itemType);
out.annotate(2, "unused"); out.annotate(2, "unused");
out.annotate(4, "Section Size: " + sectionSize); out.annotate(4, "section_size: 0x" + Integer.toHexString(sectionSize) + " (" + sectionSize + ")");
out.annotate(4, "Section Offset: " + Hex.u4(sectionOffset)); out.annotate(4, "section_off: 0x" + Integer.toHexString(sectionOffset));
} }
out.writeShort(itemType.MapValue); out.writeShort(itemType.MapValue);

View File

@ -91,9 +91,9 @@ public class MethodIdItem extends Item<MethodIdItem> {
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) { protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) { if (out.annotates()) {
out.annotate(2, classType.getConciseIdentity()); out.annotate(2, "class_type: " + classType.getTypeDescriptor());
out.annotate(2, methodPrototype.getConciseIdentity()); out.annotate(2, "method_prototype: " + methodPrototype.getPrototypeString());
out.annotate(4, methodName.getConciseIdentity()); out.annotate(4, "method_name: " + methodName.getStringValue());
} }
out.writeShort(classType.getIndex()); out.writeShort(classType.getIndex());
@ -132,8 +132,17 @@ public class MethodIdItem extends Item<MethodIdItem> {
*/ */
public String getMethodString() { public String getMethodString() {
if (cachedMethodString == null) { if (cachedMethodString == null) {
cachedMethodString = classType.getTypeDescriptor() + "->" + methodName.getStringValue() + String classType = this.classType.getTypeDescriptor();
methodPrototype.getPrototypeString(); 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; return cachedMethodString;
} }

View File

@ -99,7 +99,7 @@ public class ProtoIdItem extends Item<ProtoIdItem> {
if (parameters == null) { if (parameters == null) {
out.annotate(4, "parameters:"); out.annotate(4, "parameters:");
} else { } 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) { if (cachedPrototypeString == null) {
StringBuilder sb = new StringBuilder("("); StringBuilder sb = new StringBuilder("(");
if (parameters != null) { if (parameters != null) {
sb.append(parameters.getTypeListString()); sb.append(parameters.getTypeListString(""));
} }
sb.append(")"); sb.append(")");
sb.append(returnType.getTypeDescriptor()); sb.append(returnType.getTypeDescriptor());

View File

@ -83,11 +83,14 @@ public class StringDataItem extends Item<StringDataItem> {
protected void writeItem(AnnotatedOutput out) { protected void writeItem(AnnotatedOutput out) {
byte[] encodedValue = Utf8Utils.stringToUtf8Bytes(stringValue); byte[] encodedValue = Utf8Utils.stringToUtf8Bytes(stringValue);
if (out.annotates()) { if (out.annotates()) {
out.annotate(stringValue.length(), "string_size"); out.annotate("string_size: 0x" + Integer.toHexString(stringValue.length()) + " (" + stringValue.length() +
out.annotate(encodedValue.length + 1, "string_data (" + Utf8Utils.escapeString(stringValue) + ")"); ")");
}
out.writeUnsignedLeb128(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.write(encodedValue);
out.writeByte(0); out.writeByte(0);
} }
@ -99,7 +102,7 @@ public class StringDataItem extends Item<StringDataItem> {
/** {@inheritDoc} */ /** {@inheritDoc} */
public String getConciseIdentity() { public String getConciseIdentity() {
return "string_data_item: " + Utf8Utils.escapeString(getStringValue()); return "string_data_item: \"" + Utf8Utils.escapeString(getStringValue()) + "\"";
} }
/** {@inheritDoc} */ /** {@inheritDoc} */

View File

@ -30,6 +30,7 @@ package org.jf.dexlib;
import org.jf.dexlib.Util.Input; import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput; import org.jf.dexlib.Util.AnnotatedOutput;
import org.jf.dexlib.Util.ReadOnlyArrayList;
import java.util.List; 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 //yes, the code to write the item is duplicated. This eliminates the need to iterate over the list twice
if (out.annotates()) { if (out.annotates()) {
out.annotate(4, "size: " + typeList.length); out.annotate(4, "size: 0x" + Integer.toHexString(typeList.length) + " (" + typeList.length +")");
out.writeInt(typeList.length);
for (TypeIdItem typeIdItem: typeList) { for (TypeIdItem typeIdItem: typeList) {
out.annotate(2, typeIdItem.getConciseIdentity()); out.annotate(2, "type_id_item: " + typeIdItem.getTypeDescriptor());
out.writeShort(typeIdItem.getIndex()); }
} }
} else {
out.writeInt(typeList.length); out.writeInt(typeList.length);
for (TypeIdItem typeIdItem: typeList) { for (TypeIdItem typeIdItem: typeList) {
out.writeShort(typeIdItem.getIndex()); out.writeShort(typeIdItem.getIndex());
} }
} }
}
/** {@inheritDoc} */ /** {@inheritDoc} */
public ItemType getItemType() { public ItemType getItemType() {
@ -114,7 +111,7 @@ public class TypeListItem extends Item<TypeListItem> {
/** {@inheritDoc} */ /** {@inheritDoc} */
public String getConciseIdentity() { public String getConciseIdentity() {
return "type_list: " + getTypeListString(); return "type_list: " + getTypeListString("");
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
@ -154,22 +151,27 @@ public class TypeListItem extends Item<TypeListItem> {
return wordCount; return wordCount;
} }
private String cachedTypeListString = null;
/** /**
* @return a string consisting of the type descriptors in this <code>TypeListItem</code> * @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() { public String getTypeListString(String separator) {
int size = 0;
if (cachedTypeListString == null) { for (TypeIdItem typeIdItem: typeList) {
StringBuilder sb = new StringBuilder(); size += typeIdItem.getTypeDescriptor().length();
size += separator.length();
}
StringBuilder sb = new StringBuilder(size);
for (TypeIdItem typeIdItem: typeList) { for (TypeIdItem typeIdItem: typeList) {
sb.append(typeIdItem.getTypeDescriptor()); 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> * @return an array of the <code>TypeIdItems</code> in this <code>TypeListItem</code>
*/ */
public TypeIdItem[] getTypes() { public List<TypeIdItem> getTypes() {
return typeList.clone(); return new ReadOnlyArrayList<TypeIdItem>(typeList);
} }
/** /**

View File

@ -78,39 +78,89 @@ public enum AccessFlags
this.validForField = validForField; this.validForField = validForField;
} }
public static List<AccessFlags> getAccessFlagsForClass(int accessFlagValue) { public static AccessFlags[] getAccessFlagsForClass(int accessFlagValue) {
ArrayList<AccessFlags> accessFlags = new ArrayList<AccessFlags>(); int size = 0;
for (AccessFlags accessFlag: AccessFlags.values()) { for (AccessFlags accessFlag: AccessFlags.values()) {
if (accessFlag.validForClass && (accessFlagValue & accessFlag.value) != 0) { 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; return accessFlags;
} }
public static List<AccessFlags> getAccessFlagsForMethod(int accessFlagValue) { private static String formatAccessFlags(AccessFlags[] accessFlags) {
ArrayList<AccessFlags> accessFlags = new ArrayList<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()) { for (AccessFlags accessFlag: AccessFlags.values()) {
if (accessFlag.validForMethod && (accessFlagValue & accessFlag.value) != 0) { 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; return accessFlags;
} }
public static List<AccessFlags> getAccessFlagsForField(int accessFlagValue) { public static String formatAccessFlagsForMethod(int accessFlagValue) {
ArrayList<AccessFlags> accessFlags = new ArrayList<AccessFlags>(); return formatAccessFlags(getAccessFlagsForMethod(accessFlagValue));
}
public static AccessFlags[] getAccessFlagsForField(int accessFlagValue) {
int size = 0;
for (AccessFlags accessFlag: AccessFlags.values()) { for (AccessFlags accessFlag: AccessFlags.values()) {
if (accessFlag.validForField && (accessFlagValue & accessFlag.value) != 0) { 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; return accessFlags;
} }
public static String formatAccessFlagsForField(int accessFlagValue) {
return formatAccessFlags(getAccessFlagsForField(accessFlagValue));
}
public static AccessFlags getAccessFlag(String accessFlag) { public static AccessFlags getAccessFlag(String accessFlag) {
return accessFlagsByName.get(accessFlag); return accessFlagsByName.get(accessFlag);
} }

View File

@ -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];
}
}