1063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver/* 2063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver * Copyright 2013, Google Inc. 3063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver * All rights reserved. 4063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver * 5063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver * Redistribution and use in source and binary forms, with or without 6063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver * modification, are permitted provided that the following conditions are 7063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver * met: 8063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver * 9063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver * * Redistributions of source code must retain the above copyright 10063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver * notice, this list of conditions and the following disclaimer. 11063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver * * Redistributions in binary form must reproduce the above 12063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver * copyright notice, this list of conditions and the following disclaimer 13063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver * in the documentation and/or other materials provided with the 14063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver * distribution. 15063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver * * Neither the name of Google Inc. nor the names of its 16063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver * contributors may be used to endorse or promote products derived from 17063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver * this software without specific prior written permission. 18063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver * 19063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver */ 31063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver 32063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruverpackage org.jf.dexlib2.dexbacked.raw; 33063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver 34063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruverimport org.jf.dexlib2.DebugItemType; 35063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruverimport org.jf.dexlib2.dexbacked.DexReader; 36063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruverimport org.jf.dexlib2.dexbacked.raw.util.DexAnnotator; 37063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruverimport org.jf.dexlib2.util.AnnotatedBytes; 38063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver 39063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruverimport javax.annotation.Nonnull; 40063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruverimport javax.annotation.Nullable; 41063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver 42063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruverpublic class DebugInfoItem { 43063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver 44063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver @Nonnull 45063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver public static SectionAnnotator makeAnnotator(@Nonnull DexAnnotator annotator, @Nonnull MapItem mapItem) { 46063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver return new SectionAnnotator(annotator, mapItem) { 47063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver @Nonnull @Override public String getItemName() { 48063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver return "debug_info_item"; 49063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver } 50063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver 51063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver @Override 52063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver public void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) { 53063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver DexReader reader = dexFile.readerAt(out.getCursor()); 54063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver 55063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver int lineStart = reader.readSmallUleb128(); 56063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.annotateTo(reader.getOffset(), "line_start = %d", lineStart); 57063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver 58063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver int parametersSize = reader.readSmallUleb128(); 59063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.annotateTo(reader.getOffset(), "parameters_size = %d", parametersSize); 60063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver 61063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver if (parametersSize > 0) { 62063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.annotate(0, "parameters:"); 63063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.indent(); 64063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver for (int i=0; i<parametersSize; i++) { 65063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver int paramaterIndex = reader.readSmallUleb128() - 1; 668340ecf3d5b272ea9121ef09be2359e419aa8039Ben Gruver out.annotateTo(reader.getOffset(), "%s", 67063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver StringIdItem.getOptionalReferenceAnnotation(dexFile, paramaterIndex, true)); 68063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver } 69063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.deindent(); 70063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver } 71063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver 72063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.annotate(0, "debug opcodes:"); 73063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.indent(); 74063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver 75063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver int codeAddress = 0; 76063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver int lineNumber = lineStart; 77063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver 78063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver loop: while (true) { 79063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver int opcode = reader.readUbyte(); 80063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver switch (opcode) { 81063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver case DebugItemType.END_SEQUENCE: { 82063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.annotateTo(reader.getOffset(), "DBG_END_SEQUENCE"); 83063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver break loop; 84063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver } 85063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver case DebugItemType.ADVANCE_PC: { 86063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.annotateTo(reader.getOffset(), "DBG_ADVANCE_PC"); 87063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.indent(); 88063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver int addressDiff = reader.readSmallUleb128(); 89063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver codeAddress += addressDiff; 90063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.annotateTo(reader.getOffset(), "addr_diff = +0x%x: 0x%x", addressDiff, 91063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver codeAddress); 92063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.deindent(); 93063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver break; 94063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver } 95063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver case DebugItemType.ADVANCE_LINE: { 96063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.annotateTo(reader.getOffset(), "DBG_ADVANCE_LINE"); 97063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.indent(); 98063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver int lineDiff = reader.readSleb128(); 99063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver lineNumber += lineDiff; 100063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.annotateTo(reader.getOffset(), "line_diff = +%d: %d", Math.abs(lineDiff), lineNumber); 101063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.deindent(); 102063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver break; 103063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver } 104063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver case DebugItemType.START_LOCAL: { 105063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.annotateTo(reader.getOffset(), "DBG_START_LOCAL"); 106063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.indent(); 107063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver int registerNum = reader.readSmallUleb128(); 108063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.annotateTo(reader.getOffset(), "register_num = v%d", registerNum); 109063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver int nameIndex = reader.readSmallUleb128() - 1; 110063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.annotateTo(reader.getOffset(), "name_idx = %s", 111063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver StringIdItem.getOptionalReferenceAnnotation(dexFile, nameIndex, true)); 112063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver int typeIndex = reader.readSmallUleb128() - 1; 113063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.annotateTo(reader.getOffset(), "type_idx = %s", 114063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver TypeIdItem.getOptionalReferenceAnnotation(dexFile, typeIndex)); 115063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.deindent(); 116063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver break; 117063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver } 118063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver case DebugItemType.START_LOCAL_EXTENDED: { 119063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.annotateTo(reader.getOffset(), "DBG_START_LOCAL_EXTENDED"); 120063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.indent(); 121063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver int registerNum = reader.readSmallUleb128(); 122063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.annotateTo(reader.getOffset(), "register_num = v%d", registerNum); 123063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver int nameIndex = reader.readSmallUleb128() - 1; 124063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.annotateTo(reader.getOffset(), "name_idx = %s", 125063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver StringIdItem.getOptionalReferenceAnnotation(dexFile, nameIndex, true)); 126063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver int typeIndex = reader.readSmallUleb128() - 1; 127063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.annotateTo(reader.getOffset(), "type_idx = %s", 128063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver TypeIdItem.getOptionalReferenceAnnotation(dexFile, typeIndex)); 129063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver int sigIndex = reader.readSmallUleb128() - 1; 130063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.annotateTo(reader.getOffset(), "sig_idx = %s", 131063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver StringIdItem.getOptionalReferenceAnnotation(dexFile, sigIndex, true)); 132063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.deindent(); 133063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver break; 134063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver } 135063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver case DebugItemType.END_LOCAL: { 136063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.annotateTo(reader.getOffset(), "DBG_END_LOCAL"); 137063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.indent(); 138063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver int registerNum = reader.readSmallUleb128(); 139063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.annotateTo(reader.getOffset(), "register_num = v%d", registerNum); 140063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.deindent(); 141063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver break; 142063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver } 143063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver case DebugItemType.RESTART_LOCAL: { 144063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.annotateTo(reader.getOffset(), "DBG_RESTART_LOCAL"); 145063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.indent(); 146063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver int registerNum = reader.readSmallUleb128(); 147063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.annotateTo(reader.getOffset(), "register_num = v%d", registerNum); 148063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.deindent(); 149063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver break; 150063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver } 151063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver case DebugItemType.PROLOGUE_END: { 152063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.annotateTo(reader.getOffset(), "DBG_SET_PROLOGUE_END"); 153063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver break; 154063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver } 155063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver case DebugItemType.EPILOGUE_BEGIN: { 156063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.annotateTo(reader.getOffset(), "DBG_SET_EPILOGUE_BEGIN"); 157063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver break; 158063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver } 159063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver case DebugItemType.SET_SOURCE_FILE: { 160063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.annotateTo(reader.getOffset(), "DBG_SET_FILE"); 161063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.indent(); 162063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver int nameIdx = reader.readSmallUleb128() - 1; 163063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.annotateTo(reader.getOffset(), "name_idx = %s", 164063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver StringIdItem.getOptionalReferenceAnnotation(dexFile, nameIdx)); 165063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.deindent(); 166063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver break; 167063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver } 168063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver default: 169063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver int adjusted = opcode - 0x0A; 170063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver int addressDiff = adjusted / 15; 171063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver int lineDiff = (adjusted % 15) - 4; 172063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver codeAddress += addressDiff; 173063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver lineNumber += lineDiff; 174063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.annotateTo(reader.getOffset(), "address_diff = +0x%x:0x%x, line_diff = +%d:%d, ", 175063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver addressDiff, codeAddress, lineDiff, lineNumber); 176063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver break; 177063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver } 178063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver } 179063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver out.deindent(); 180063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver } 181063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver }; 182063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver } 183063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver} 184