16d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver/* 26d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver * Copyright 2013, Google Inc. 36d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver * All rights reserved. 46d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver * 56d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver * Redistribution and use in source and binary forms, with or without 66d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver * modification, are permitted provided that the following conditions are 76d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver * met: 86d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver * 96d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver * * Redistributions of source code must retain the above copyright 106d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver * notice, this list of conditions and the following disclaimer. 116d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver * * Redistributions in binary form must reproduce the above 126d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver * copyright notice, this list of conditions and the following disclaimer 136d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver * in the documentation and/or other materials provided with the 146d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver * distribution. 156d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver * * Neither the name of Google Inc. nor the names of its 166d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver * contributors may be used to endorse or promote products derived from 176d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver * this software without specific prior written permission. 186d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver * 196d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 206d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 216d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 226d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 236d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 246d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 256d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 266d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 276d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 286d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 296d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 306d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver */ 316d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver 326d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruverpackage org.jf.dexlib2.dexbacked.raw; 336d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver 346d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruverimport com.google.common.base.Joiner; 356d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruverimport com.google.common.collect.Lists; 36db7795ffaa2d8804d84623a79d406f8c8686c1b8Ben Gruverimport org.jf.dexlib2.VerificationError; 376d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruverimport org.jf.dexlib2.dexbacked.DexReader; 386d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruverimport org.jf.dexlib2.dexbacked.instruction.DexBackedInstruction; 398f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruverimport org.jf.dexlib2.dexbacked.raw.util.DexAnnotator; 406d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruverimport org.jf.dexlib2.iface.instruction.*; 416d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruverimport org.jf.dexlib2.iface.instruction.formats.*; 426d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruverimport org.jf.dexlib2.util.AnnotatedBytes; 436d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruverimport org.jf.dexlib2.util.ReferenceUtil; 44dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruverimport org.jf.util.ExceptionWithContext; 456d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruverimport org.jf.util.NumberUtils; 466d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver 476d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruverimport javax.annotation.Nonnull; 486d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruverimport javax.annotation.Nullable; 496d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruverimport java.util.List; 506d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver 516d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruverpublic class CodeItem { 526d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver public static final int REGISTERS_OFFSET = 0; 536d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver public static final int INS_OFFSET = 2; 546d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver public static final int OUTS_OFFSET = 4; 55e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruver public static final int TRIES_SIZE_OFFSET = 6; 566d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver public static final int DEBUG_INFO_OFFSET = 8; 576d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver public static final int INSTRUCTION_COUNT_OFFSET = 12; 58e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruver public static final int INSTRUCTION_START_OFFSET = 16; 59e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruver 60e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruver public static class TryItem { 61e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruver public static final int ITEM_SIZE = 8; 62e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruver 63e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruver public static final int START_ADDRESS_OFFSET = 0; 64e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruver public static final int CODE_UNIT_COUNT_OFFSET = 4; 65e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruver public static final int HANDLER_OFFSET = 6; 66e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruver } 676d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver 688f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver @Nonnull 698f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver public static SectionAnnotator makeAnnotator(@Nonnull DexAnnotator annotator, @Nonnull MapItem mapItem) { 708f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver return new SectionAnnotator(annotator, mapItem) { 71063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver private SectionAnnotator debugInfoAnnotator = null; 72063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver 73063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver @Override public void annotateSection(@Nonnull AnnotatedBytes out) { 74063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver debugInfoAnnotator = annotator.getAnnotator(ItemType.DEBUG_INFO_ITEM); 75063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver super.annotateSection(out); 76063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver } 77063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver 788f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver @Nonnull @Override public String getItemName() { 798f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver return "code_item"; 808f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } 816d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver 828f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver @Override public int getItemAlignment() { 838f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver return 4; 846d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver } 856d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver 868f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver @Override 878f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver public void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) { 88dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver try { 89dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver DexReader reader = dexFile.readerAt(out.getCursor()); 908f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver 91dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver int registers = reader.readUshort(); 92dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.annotate(2, "registers_size = %d", registers); 938f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver 94dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver int inSize = reader.readUshort(); 95dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.annotate(2, "ins_size = %d", inSize); 968f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver 97dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver int outSize = reader.readUshort(); 98dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.annotate(2, "outs_size = %d", outSize); 998f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver 100dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver int triesCount = reader.readUshort(); 101dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.annotate(2, "tries_size = %d", triesCount); 1028f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver 103dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver int debugInfoOffset = reader.readSmallUint(); 104dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.annotate(4, "debug_info_off = 0x%x", debugInfoOffset); 1058f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver 106dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver if (debugInfoOffset != 0) { 107dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver addDebugInfoIdentity(debugInfoOffset, itemIdentity); 1088f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } 1096d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver 110dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver int instructionSize = reader.readSmallUint(); 111dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.annotate(4, "insns_size = 0x%x", instructionSize); 1128f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver 113dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.annotate(0, "instructions:"); 1146d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver out.indent(); 1158f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver 116dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.setLimit(out.getCursor(), out.getCursor() + instructionSize * 2); 117dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver 118dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver int end = reader.getOffset() + instructionSize*2; 119dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver try { 120dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver while (reader.getOffset() < end) { 121dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver Instruction instruction = DexBackedInstruction.readFrom(reader); 122dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver 123dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver // if we read past the end of the instruction list 124dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver if (reader.getOffset() > end) { 125dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.annotateTo(end, "truncated instruction"); 126dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver reader.setOffset(end); 127dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver } else { 128dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver switch (instruction.getOpcode().format) { 129dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver case Format10x: 130dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver annotateInstruction10x(out, instruction); 131dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver break; 132dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver case Format35c: 133dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver annotateInstruction35c(out, (Instruction35c)instruction); 134dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver break; 135dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver case Format3rc: 136dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver annotateInstruction3rc(out, (Instruction3rc)instruction); 137dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver break; 138dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver case ArrayPayload: 139dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver annotateArrayPayload(out, (ArrayPayload)instruction); 140dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver break; 141dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver case PackedSwitchPayload: 142dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver annotatePackedSwitchPayload(out, (PackedSwitchPayload)instruction); 143dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver break; 144dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver case SparseSwitchPayload: 145dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver annotateSparseSwitchPayload(out, (SparseSwitchPayload)instruction); 146dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver break; 147dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver default: 148dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver annotateDefaultInstruction(out, instruction); 149dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver break; 150dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver } 151dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver } 1526d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver 153dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver assert reader.getOffset() == out.getCursor(); 154dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver } 155dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver } catch (ExceptionWithContext ex) { 156dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver ex.printStackTrace(System.err); 157dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.annotate(0, "annotation error: %s", ex.getMessage()); 158dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.moveTo(end); 159dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver reader.setOffset(end); 160dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver } finally { 161dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.clearLimit(); 1628f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.deindent(); 1638f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } 1648f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver 165dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver if (triesCount > 0) { 166dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver if ((reader.getOffset() % 4) != 0) { 167dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver reader.readUshort(); 168dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.annotate(2, "padding"); 169dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver } 170dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver 171dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.annotate(0, "try_items:"); 1728f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.indent(); 173dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver try { 174dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver for (int i=0; i<triesCount; i++) { 175dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.annotate(0, "try_item[%d]:", i); 1768f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.indent(); 177dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver try { 178dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver int startAddr = reader.readSmallUint(); 179dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.annotate(4, "start_addr = 0x%x", startAddr); 180dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver 181dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver int instructionCount = reader.readUshort(); 182dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.annotate(2, "insn_count = 0x%x", instructionCount); 183dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver 184dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver int handlerOffset = reader.readUshort(); 185dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.annotate(2, "handler_off = 0x%x", handlerOffset); 186dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver } finally { 187dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.deindent(); 188dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver } 1898f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } 190dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver } finally { 1916d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver out.deindent(); 1926d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver } 193dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver 194dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver int handlerListCount = reader.readSmallUleb128(); 195dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.annotate(0, "encoded_catch_handler_list:"); 196dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.annotateTo(reader.getOffset(), "size = %d", handlerListCount); 197dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.indent(); 198dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver try { 199dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver for (int i=0; i<handlerListCount; i++) { 200dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.annotate(0, "encoded_catch_handler[%d]", i); 201dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.indent(); 202dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver try { 203dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver int handlerCount = reader.readSleb128(); 204dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.annotateTo(reader.getOffset(), "size = %d", handlerCount); 205dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver boolean hasCatchAll = handlerCount <= 0; 206dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver handlerCount = Math.abs(handlerCount); 207dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver if (handlerCount != 0) { 208dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.annotate(0, "handlers:"); 209dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.indent(); 210dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver try { 211dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver for (int j=0; j<handlerCount; j++) { 212dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.annotate(0, "encoded_type_addr_pair[%d]", i); 213dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.indent(); 214dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver try { 215dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver int typeIndex = reader.readSmallUleb128(); 216dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.annotateTo(reader.getOffset(), TypeIdItem.getReferenceAnnotation(dexFile, typeIndex)); 217dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver 218dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver int handlerAddress = reader.readSmallUleb128(); 219dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.annotateTo(reader.getOffset(), "addr = 0x%x", handlerAddress); 220dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver } finally { 221dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.deindent(); 222dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver } 223dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver } 224dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver } finally { 225dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.deindent(); 226dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver } 227dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver } 228dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver if (hasCatchAll) { 229dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver int catchAllAddress = reader.readSmallUleb128(); 230dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.annotateTo(reader.getOffset(), "catch_all_addr = 0x%x", catchAllAddress); 231dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver } 232dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver } finally { 233dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.deindent(); 234dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver } 235dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver } 236dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver } finally { 237dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.deindent(); 2388f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } 2396d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver } 240dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver } catch (ExceptionWithContext ex) { 241dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver out.annotate(0, "annotation error: %s", ex.getMessage()); 2426d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver } 2436d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver } 2446d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver 2458f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver private String formatRegister(int registerNum) { 2468f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver return String.format("v%d", registerNum); 2478f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } 2486d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver 2498f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver private void annotateInstruction10x(@Nonnull AnnotatedBytes out, @Nonnull Instruction instruction) { 2508f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotate(2, instruction.getOpcode().name); 2516d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver } 2526d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver 2538f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver private void annotateInstruction35c(@Nonnull AnnotatedBytes out, @Nonnull Instruction35c instruction) { 2548f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver List<String> args = Lists.newArrayList(); 2558f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver 2568f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver int registerCount = instruction.getRegisterCount(); 2578f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver if (registerCount == 1) { 2588f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver args.add(formatRegister(instruction.getRegisterC())); 2598f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } else if (registerCount == 2) { 2608f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver args.add(formatRegister(instruction.getRegisterC())); 2618f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver args.add(formatRegister(instruction.getRegisterD())); 2628f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } else if (registerCount == 3) { 2638f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver args.add(formatRegister(instruction.getRegisterC())); 2648f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver args.add(formatRegister(instruction.getRegisterD())); 2658f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver args.add(formatRegister(instruction.getRegisterE())); 2668f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } else if (registerCount == 4) { 2678f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver args.add(formatRegister(instruction.getRegisterC())); 2688f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver args.add(formatRegister(instruction.getRegisterD())); 2698f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver args.add(formatRegister(instruction.getRegisterE())); 2708f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver args.add(formatRegister(instruction.getRegisterF())); 2718f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } else if (registerCount == 5) { 2728f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver args.add(formatRegister(instruction.getRegisterC())); 2738f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver args.add(formatRegister(instruction.getRegisterD())); 2748f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver args.add(formatRegister(instruction.getRegisterE())); 2758f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver args.add(formatRegister(instruction.getRegisterF())); 2768f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver args.add(formatRegister(instruction.getRegisterG())); 2776d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver } 2786d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver 2798f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver String reference = ReferenceUtil.getReferenceString(instruction.getReference()); 2808f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver 2818f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotate(6, String.format("%s {%s}, %s", 2828f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver instruction.getOpcode().name, Joiner.on(", ").join(args), reference)); 2836d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver } 2846d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver 2858f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver private void annotateInstruction3rc(@Nonnull AnnotatedBytes out, @Nonnull Instruction3rc instruction) { 2868f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver int startRegister = instruction.getStartRegister(); 2878f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver int endRegister = startRegister + instruction.getRegisterCount() - 1; 2888f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver String reference = ReferenceUtil.getReferenceString(instruction.getReference()); 2898f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotate(6, String.format("%s {%s .. %s}, %s", 2908f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver instruction.getOpcode().name, formatRegister(startRegister), formatRegister(endRegister), 2918f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver reference)); 2926d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver } 2936d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver 2948f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver private void annotateDefaultInstruction(@Nonnull AnnotatedBytes out, @Nonnull Instruction instruction) { 2958f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver List<String> args = Lists.newArrayList(); 2968f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver 2978f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver if (instruction instanceof OneRegisterInstruction) { 2988f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver args.add(formatRegister(((OneRegisterInstruction)instruction).getRegisterA())); 2998f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver if (instruction instanceof TwoRegisterInstruction) { 3008f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver args.add(formatRegister(((TwoRegisterInstruction)instruction).getRegisterB())); 3018f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver if (instruction instanceof ThreeRegisterInstruction) { 3028f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver args.add(formatRegister(((ThreeRegisterInstruction)instruction).getRegisterC())); 3038f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } 3048f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } 305db7795ffaa2d8804d84623a79d406f8c8686c1b8Ben Gruver } else if (instruction instanceof VerificationErrorInstruction) { 306dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver String verificationError = VerificationError.getVerificationErrorName( 307dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver ((VerificationErrorInstruction) instruction).getVerificationError()); 308dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver if (verificationError != null) { 309dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver args.add(verificationError); 310dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver } else { 311dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver args.add("invalid verification error type"); 312dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver } 3138f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } 3148f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver 3158f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver if (instruction instanceof ReferenceInstruction) { 316dc802b06607cde3eadaaffeae888bfd6146000f1Ben Gruver args.add(ReferenceUtil.getReferenceString(((ReferenceInstruction)instruction).getReference())); 3178a151ae671f6d5c99d55779005580834b49187f0Ben Gruver } else if (instruction instanceof OffsetInstruction) { 3188f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver int offset = ((OffsetInstruction)instruction).getCodeOffset(); 3198f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver String sign = offset>=0?"+":"-"; 32070c5b247e69463338f0b61fd6a9774f439b31bd7Ben Gruver args.add(String.format("%s0x%x", sign, Math.abs(offset))); 3218a151ae671f6d5c99d55779005580834b49187f0Ben Gruver } else if (instruction instanceof NarrowLiteralInstruction) { 3228f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver int value = ((NarrowLiteralInstruction)instruction).getNarrowLiteral(); 3238f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver if (NumberUtils.isLikelyFloat(value)) { 3248f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver args.add(String.format("%d # %f", value, Float.intBitsToFloat(value))); 3256d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver } else { 3268f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver args.add(String.format("%d", value)); 3276d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver } 3288f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } else if (instruction instanceof WideLiteralInstruction) { 3298f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver long value = ((WideLiteralInstruction)instruction).getWideLiteral(); 3308f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver if (NumberUtils.isLikelyDouble(value)) { 3318f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver args.add(String.format("%d # %f", value, Double.longBitsToDouble(value))); 3326d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver } else { 3338f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver args.add(String.format("%d", value)); 3346d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver } 3358a151ae671f6d5c99d55779005580834b49187f0Ben Gruver } else if (instruction instanceof FieldOffsetInstruction) { 336e88723c666db87d414e126ac6d94d683d86ad28dBen Gruver int fieldOffset = ((FieldOffsetInstruction)instruction).getFieldOffset(); 337e88723c666db87d414e126ac6d94d683d86ad28dBen Gruver args.add(String.format("field@0x%x", fieldOffset)); 3388a151ae671f6d5c99d55779005580834b49187f0Ben Gruver } else if (instruction instanceof VtableIndexInstruction) { 3398a151ae671f6d5c99d55779005580834b49187f0Ben Gruver int vtableIndex = ((VtableIndexInstruction)instruction).getVtableIndex(); 3408a151ae671f6d5c99d55779005580834b49187f0Ben Gruver args.add(String.format("vtable@%d", vtableIndex)); 3412a91d72a1534dd8171d8296ce8312de4bd603451Ben Gruver } else if (instruction instanceof InlineIndexInstruction) { 3422a91d72a1534dd8171d8296ce8312de4bd603451Ben Gruver int inlineIndex = ((InlineIndexInstruction)instruction).getInlineIndex(); 3432a91d72a1534dd8171d8296ce8312de4bd603451Ben Gruver args.add(String.format("inline@%d", inlineIndex)); 344e88723c666db87d414e126ac6d94d683d86ad28dBen Gruver } 345e88723c666db87d414e126ac6d94d683d86ad28dBen Gruver 3468f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotate(instruction.getCodeUnits()*2, "%s %s", 3478f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver instruction.getOpcode().name, Joiner.on(", ").join(args)); 3486d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver } 3496d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver 3508f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver private void annotateArrayPayload(@Nonnull AnnotatedBytes out, @Nonnull ArrayPayload instruction) { 3518f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver List<Number> elements = instruction.getArrayElements(); 3528f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver int elementWidth = instruction.getElementWidth(); 3536d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver 3548f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotate(2, instruction.getOpcode().name); 3558f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.indent(); 3568f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotate(2, "element_width = %d", elementWidth); 3578f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotate(4, "size = %d", elements.size()); 3588f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotate(0, "elements:"); 3598f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.indent(); 3608f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver for (int i=0; i<elements.size(); i++) { 3618f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver if (elementWidth == 8) { 3628f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver long value = elements.get(i).longValue(); 3638f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver if (NumberUtils.isLikelyDouble(value)) { 3648f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotate(elementWidth, "element[%d] = %d # %f", i, value, Double.longBitsToDouble(value)); 3658f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } else { 3668f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotate(elementWidth, "element[%d] = %d", i, value); 3678f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } 3688f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } else { 3698f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver int value = elements.get(i).intValue(); 3708f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver if (NumberUtils.isLikelyFloat(value)) { 3718f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotate(elementWidth, "element[%d] = %d # %f", i, value, Float.intBitsToFloat(value)); 3728f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } else { 3738f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotate(elementWidth, "element[%d] = %d", i, value); 3746d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver } 3756d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver } 3768f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } 3778f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver if (out.getCursor() % 2 != 0) { 3788f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotate(1, "padding"); 3798f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } 3808f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.deindent(); 3818f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.deindent(); 3828f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } 3838f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver 3848f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver private void annotatePackedSwitchPayload(@Nonnull AnnotatedBytes out, 3858f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver @Nonnull PackedSwitchPayload instruction) { 3868f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver List<? extends SwitchElement> elements = instruction.getSwitchElements(); 3878f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver 3888f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotate(2, instruction.getOpcode().name); 3898f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.indent(); 3908f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver 3918f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotate(2, "size = %d", elements.size()); 392c89097680ec8d7d2495b7314c848af3507cf515fBen Gruver if (elements.size() == 0) { 393c89097680ec8d7d2495b7314c848af3507cf515fBen Gruver out.annotate(4, "first_key"); 394c89097680ec8d7d2495b7314c848af3507cf515fBen Gruver } else { 395c89097680ec8d7d2495b7314c848af3507cf515fBen Gruver out.annotate(4, "first_key = %d", elements.get(0).getKey()); 396c89097680ec8d7d2495b7314c848af3507cf515fBen Gruver out.annotate(0, "targets:"); 397c89097680ec8d7d2495b7314c848af3507cf515fBen Gruver out.indent(); 398c89097680ec8d7d2495b7314c848af3507cf515fBen Gruver for (int i=0; i<elements.size(); i++) { 399c89097680ec8d7d2495b7314c848af3507cf515fBen Gruver out.annotate(4, "target[%d] = %d", i, elements.get(i).getOffset()); 400c89097680ec8d7d2495b7314c848af3507cf515fBen Gruver } 401c89097680ec8d7d2495b7314c848af3507cf515fBen Gruver out.deindent(); 4028f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } 4038f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.deindent(); 4048f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } 4058f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver 4068f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver private void annotateSparseSwitchPayload(@Nonnull AnnotatedBytes out, 4078f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver @Nonnull SparseSwitchPayload instruction) { 4088f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver List<? extends SwitchElement> elements = instruction.getSwitchElements(); 4098f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver 4108f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotate(2, instruction.getOpcode().name); 4118f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.indent(); 4128f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotate(2, "size = %d", elements.size()); 4132fe6041fa9e2e2eab534a7da086006835c8f59f6Ben Gruver if (elements.size() > 0) { 4142fe6041fa9e2e2eab534a7da086006835c8f59f6Ben Gruver out.annotate(0, "keys:"); 4152fe6041fa9e2e2eab534a7da086006835c8f59f6Ben Gruver out.indent(); 4162fe6041fa9e2e2eab534a7da086006835c8f59f6Ben Gruver for (int i=0; i<elements.size(); i++) { 4172fe6041fa9e2e2eab534a7da086006835c8f59f6Ben Gruver out.annotate(4, "key[%d] = %d", i, elements.get(i).getKey()); 4182fe6041fa9e2e2eab534a7da086006835c8f59f6Ben Gruver } 4192fe6041fa9e2e2eab534a7da086006835c8f59f6Ben Gruver out.deindent(); 4202fe6041fa9e2e2eab534a7da086006835c8f59f6Ben Gruver out.annotate(0, "targets:"); 4212fe6041fa9e2e2eab534a7da086006835c8f59f6Ben Gruver out.indent(); 4222fe6041fa9e2e2eab534a7da086006835c8f59f6Ben Gruver for (int i=0; i<elements.size(); i++) { 4232fe6041fa9e2e2eab534a7da086006835c8f59f6Ben Gruver out.annotate(4, "target[%d] = %d", i, elements.get(i).getOffset()); 4242fe6041fa9e2e2eab534a7da086006835c8f59f6Ben Gruver } 4252fe6041fa9e2e2eab534a7da086006835c8f59f6Ben Gruver out.deindent(); 4268f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } 4278f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.deindent(); 4286d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver } 429063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver 430063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver private void addDebugInfoIdentity(int debugInfoOffset, String methodString) { 431063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver if (debugInfoAnnotator != null) { 432063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver debugInfoAnnotator.setItemIdentity(debugInfoOffset, methodString); 433063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver } 434063ec54b929a38f6b56cb667f8d08e23f92b62f7Ben Gruver } 4356d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver }; 4366d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver } 4376d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver} 438