1 /* 2 * Copyright 2013, Google Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * * Redistributions in binary form must reproduce the above 12 * copyright notice, this list of conditions and the following disclaimer 13 * in the documentation and/or other materials provided with the 14 * distribution. 15 * * Neither the name of Google Inc. nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 package org.jf.dexlib2.dexbacked.raw; 33 34 import org.jf.dexlib2.DebugItemType; 35 import org.jf.dexlib2.dexbacked.DexReader; 36 import org.jf.dexlib2.dexbacked.raw.util.DexAnnotator; 37 import org.jf.dexlib2.util.AnnotatedBytes; 38 39 import javax.annotation.Nonnull; 40 import javax.annotation.Nullable; 41 42 public class DebugInfoItem { 43 44 @Nonnull makeAnnotator(@onnull DexAnnotator annotator, @Nonnull MapItem mapItem)45 public static SectionAnnotator makeAnnotator(@Nonnull DexAnnotator annotator, @Nonnull MapItem mapItem) { 46 return new SectionAnnotator(annotator, mapItem) { 47 @Nonnull @Override public String getItemName() { 48 return "debug_info_item"; 49 } 50 51 @Override 52 public void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) { 53 DexReader reader = dexFile.readerAt(out.getCursor()); 54 55 int lineStart = reader.readBigUleb128(); 56 out.annotateTo(reader.getOffset(), "line_start = %d", lineStart & 0xFFFFFFFFL); 57 58 int parametersSize = reader.readSmallUleb128(); 59 out.annotateTo(reader.getOffset(), "parameters_size = %d", parametersSize); 60 61 if (parametersSize > 0) { 62 out.annotate(0, "parameters:"); 63 out.indent(); 64 for (int i=0; i<parametersSize; i++) { 65 int paramaterIndex = reader.readSmallUleb128() - 1; 66 out.annotateTo(reader.getOffset(), "%s", 67 StringIdItem.getOptionalReferenceAnnotation(dexFile, paramaterIndex, true)); 68 } 69 out.deindent(); 70 } 71 72 out.annotate(0, "debug opcodes:"); 73 out.indent(); 74 75 int codeAddress = 0; 76 int lineNumber = lineStart; 77 78 loop: while (true) { 79 int opcode = reader.readUbyte(); 80 switch (opcode) { 81 case DebugItemType.END_SEQUENCE: { 82 out.annotateTo(reader.getOffset(), "DBG_END_SEQUENCE"); 83 break loop; 84 } 85 case DebugItemType.ADVANCE_PC: { 86 out.annotateTo(reader.getOffset(), "DBG_ADVANCE_PC"); 87 out.indent(); 88 int addressDiff = reader.readSmallUleb128(); 89 codeAddress += addressDiff; 90 out.annotateTo(reader.getOffset(), "addr_diff = +0x%x: 0x%x", addressDiff, 91 codeAddress); 92 out.deindent(); 93 break; 94 } 95 case DebugItemType.ADVANCE_LINE: { 96 out.annotateTo(reader.getOffset(), "DBG_ADVANCE_LINE"); 97 out.indent(); 98 int lineDiff = reader.readSleb128(); 99 lineNumber += lineDiff; 100 out.annotateTo(reader.getOffset(), "line_diff = +%d: %d", Math.abs(lineDiff), lineNumber); 101 out.deindent(); 102 break; 103 } 104 case DebugItemType.START_LOCAL: { 105 out.annotateTo(reader.getOffset(), "DBG_START_LOCAL"); 106 out.indent(); 107 int registerNum = reader.readSmallUleb128(); 108 out.annotateTo(reader.getOffset(), "register_num = v%d", registerNum); 109 int nameIndex = reader.readSmallUleb128() - 1; 110 out.annotateTo(reader.getOffset(), "name_idx = %s", 111 StringIdItem.getOptionalReferenceAnnotation(dexFile, nameIndex, true)); 112 int typeIndex = reader.readSmallUleb128() - 1; 113 out.annotateTo(reader.getOffset(), "type_idx = %s", 114 TypeIdItem.getOptionalReferenceAnnotation(dexFile, typeIndex)); 115 out.deindent(); 116 break; 117 } 118 case DebugItemType.START_LOCAL_EXTENDED: { 119 out.annotateTo(reader.getOffset(), "DBG_START_LOCAL_EXTENDED"); 120 out.indent(); 121 int registerNum = reader.readSmallUleb128(); 122 out.annotateTo(reader.getOffset(), "register_num = v%d", registerNum); 123 int nameIndex = reader.readSmallUleb128() - 1; 124 out.annotateTo(reader.getOffset(), "name_idx = %s", 125 StringIdItem.getOptionalReferenceAnnotation(dexFile, nameIndex, true)); 126 int typeIndex = reader.readSmallUleb128() - 1; 127 out.annotateTo(reader.getOffset(), "type_idx = %s", 128 TypeIdItem.getOptionalReferenceAnnotation(dexFile, typeIndex)); 129 int sigIndex = reader.readSmallUleb128() - 1; 130 out.annotateTo(reader.getOffset(), "sig_idx = %s", 131 StringIdItem.getOptionalReferenceAnnotation(dexFile, sigIndex, true)); 132 out.deindent(); 133 break; 134 } 135 case DebugItemType.END_LOCAL: { 136 out.annotateTo(reader.getOffset(), "DBG_END_LOCAL"); 137 out.indent(); 138 int registerNum = reader.readSmallUleb128(); 139 out.annotateTo(reader.getOffset(), "register_num = v%d", registerNum); 140 out.deindent(); 141 break; 142 } 143 case DebugItemType.RESTART_LOCAL: { 144 out.annotateTo(reader.getOffset(), "DBG_RESTART_LOCAL"); 145 out.indent(); 146 int registerNum = reader.readSmallUleb128(); 147 out.annotateTo(reader.getOffset(), "register_num = v%d", registerNum); 148 out.deindent(); 149 break; 150 } 151 case DebugItemType.PROLOGUE_END: { 152 out.annotateTo(reader.getOffset(), "DBG_SET_PROLOGUE_END"); 153 break; 154 } 155 case DebugItemType.EPILOGUE_BEGIN: { 156 out.annotateTo(reader.getOffset(), "DBG_SET_EPILOGUE_BEGIN"); 157 break; 158 } 159 case DebugItemType.SET_SOURCE_FILE: { 160 out.annotateTo(reader.getOffset(), "DBG_SET_FILE"); 161 out.indent(); 162 int nameIdx = reader.readSmallUleb128() - 1; 163 out.annotateTo(reader.getOffset(), "name_idx = %s", 164 StringIdItem.getOptionalReferenceAnnotation(dexFile, nameIdx)); 165 out.deindent(); 166 break; 167 } 168 default: 169 int adjusted = opcode - 0x0A; 170 int addressDiff = adjusted / 15; 171 int lineDiff = (adjusted % 15) - 4; 172 codeAddress += addressDiff; 173 lineNumber += lineDiff; 174 out.annotateTo(reader.getOffset(), "address_diff = +0x%x:0x%x, line_diff = +%d:%d, ", 175 addressDiff, codeAddress, lineDiff, lineNumber); 176 break; 177 } 178 } 179 out.deindent(); 180 } 181 }; 182 } 183 } 184