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