1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.android.dx.dex.file; 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 19fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dex.util.ExceptionWithContext; 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.dex.code.LocalList; 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.dex.code.PositionList; 22fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport static com.android.dx.dex.file.DebugInfoConstants.DBG_ADVANCE_LINE; 23fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport static com.android.dx.dex.file.DebugInfoConstants.DBG_ADVANCE_PC; 24fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport static com.android.dx.dex.file.DebugInfoConstants.DBG_END_LOCAL; 25fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport static com.android.dx.dex.file.DebugInfoConstants.DBG_END_SEQUENCE; 26fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport static com.android.dx.dex.file.DebugInfoConstants.DBG_FIRST_SPECIAL; 27fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport static com.android.dx.dex.file.DebugInfoConstants.DBG_LINE_BASE; 28fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport static com.android.dx.dex.file.DebugInfoConstants.DBG_LINE_RANGE; 29fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport static com.android.dx.dex.file.DebugInfoConstants.DBG_RESTART_LOCAL; 30fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport static com.android.dx.dex.file.DebugInfoConstants.DBG_SET_PROLOGUE_END; 31fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport static com.android.dx.dex.file.DebugInfoConstants.DBG_START_LOCAL; 32fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport static com.android.dx.dex.file.DebugInfoConstants.DBG_START_LOCAL_EXTENDED; 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.RegisterSpec; 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.SourcePosition; 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstMethodRef; 36333201833d506a3accdeac6ceb7caba8d4b95797Jesse Wilsonimport com.android.dx.rop.cst.CstString; 37fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dx.rop.cst.CstType; 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.Prototype; 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.StdTypeList; 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.Type; 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.AnnotatedOutput; 42fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dx.util.ByteArrayAnnotatedOutput; 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.IOException; 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.PrintWriter; 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.ArrayList; 46fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport java.util.BitSet; 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Collections; 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Comparator; 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * An encoder for the dex debug info state machine format. The format 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * for each method enrty is as follows: 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <ol> 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <li> signed LEB128: initial value for line register. 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <li> n instances of signed LEB128: string indicies (offset by 1) 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * for each method argument in left-to-right order 5799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * with {@code this} excluded. A value of '0' indicates "no name" 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <li> A sequence of special or normal opcodes as defined in 5999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code DebugInfoConstants}. 6099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * <li> A single terminating {@code OP_END_SEQUENCE} 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * </ol> 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class DebugInfoEncoder { 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final boolean DEBUG = false; 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 6699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code null-ok;} positions (line numbers) to encode */ 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final PositionList positions; 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 6999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code null-ok;} local variables to encode */ 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final LocalList locals; 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final ByteArrayAnnotatedOutput output; 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final DexFile file; 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final int codeSize; 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final int regSize; 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final Prototype desc; 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final boolean isStatic; 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** current encoding state: bytecode address */ 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int address = 0; 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** current encoding state: line number */ 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int line = 1; 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if non-null: the output to write annotations to. No normal 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * output is written to this. 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private AnnotatedOutput annotateTo; 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** if non-null: another possible output for annotations */ 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private PrintWriter debugPrint; 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** if non-null: the prefix for each annotation or debugPrint line */ 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private String prefix; 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** true if output should be consumed during annotation */ 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private boolean shouldConsume; 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** indexed by register; last local alive in register */ 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final LocalList.Entry[] lastEntryForReg; 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Creates an instance. 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 107f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein * @param positions {@code null-ok;} positions (line numbers) to encode 108f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein * @param locals {@code null-ok;} local variables to encode 10999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param file {@code null-ok;} may only be {@code null} if simply using 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this class to do a debug print 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param codeSize 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param regSize 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param isStatic 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param ref 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 116f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein public DebugInfoEncoder(PositionList positions, LocalList locals, 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexFile file, int codeSize, int regSize, 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean isStatic, CstMethodRef ref) { 119f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein this.positions = positions; 120f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein this.locals = locals; 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.file = file; 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.desc = ref.getPrototype(); 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.isStatic = isStatic; 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.codeSize = codeSize; 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.regSize = regSize; 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 127f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein output = new ByteArrayAnnotatedOutput(); 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lastEntryForReg = new LocalList.Entry[regSize]; 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 13299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Annotates or writes a message to the {@code debugPrint} writer 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if applicable. 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param length the number of bytes associated with this message 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param message the message itself 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void annotate(int length, String message) { 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (prefix != null) { 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project message = prefix + message; 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annotateTo != null) { 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project annotateTo.annotate(shouldConsume ? length : 0, message); 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (debugPrint != null) { 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project debugPrint.println(message); 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Converts this (PositionList, LocalList) pair into a state machine 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * sequence. 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 15699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} encoded byte sequence without padding and 15799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * terminated with a {@code 0x00} byte 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public byte[] convert() { 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] ret; 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ret = convert0(); 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (DEBUG) { 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0 ; i < ret.length; i++) { 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.err.printf("byte %02x\n", (0xff & ret[i])); 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ret; 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (IOException ex) { 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw ExceptionWithContext 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project .withContext(ex, "...while encoding debug info"); 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Converts and produces annotations on a stream. Does not write 17999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * actual bits to the {@code AnnotatedOutput}. 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 18199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param prefix {@code null-ok;} prefix to attach to each line of output 18299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param debugPrint {@code null-ok;} if specified, an alternate output for 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * annotations 18499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param out {@code null-ok;} if specified, where annotations should go 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param consume whether to claim to have consumed output for 18699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code out} 18799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} encoded output 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public byte[] convertAndAnnotate(String prefix, PrintWriter debugPrint, 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AnnotatedOutput out, boolean consume) { 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.prefix = prefix; 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.debugPrint = debugPrint; 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project annotateTo = out; 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project shouldConsume = consume; 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] result = convert(); 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 200f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private byte[] convert0() throws IOException { 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayList<PositionList.Entry> sortedPositions = buildSortedPositions(); 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayList<LocalList.Entry> methodArgs = extractMethodArguments(); 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project emitHeader(sortedPositions, methodArgs); 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // TODO: Make this mark be the actual prologue end. 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project output.writeByte(DBG_SET_PROLOGUE_END); 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annotateTo != null || debugPrint != null) { 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project annotate(1, String.format("%04x: prologue end",address)); 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 214f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein int positionsSz = sortedPositions.size(); 215f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein int localsSz = locals.size(); 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Current index in sortedPositions 218f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein int curPositionIdx = 0; 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Current index in locals 220f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein int curLocalIdx = 0; 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (;;) { 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Emit any information for the current address. 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 227f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein curLocalIdx = emitLocalsAtAddress(curLocalIdx); 228f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein curPositionIdx = 229f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein emitPositionsAtAddress(curPositionIdx, sortedPositions); 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Figure out what the next important address is. 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int nextAddrL = Integer.MAX_VALUE; // local variable 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int nextAddrP = Integer.MAX_VALUE; // position (line number) 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 238f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein if (curLocalIdx < localsSz) { 239f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein nextAddrL = locals.get(curLocalIdx).getAddress(); 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 242f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein if (curPositionIdx < positionsSz) { 243f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein nextAddrP = sortedPositions.get(curPositionIdx).getAddress(); 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int next = Math.min(nextAddrP, nextAddrL); 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // No next important address == done. 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (next == Integer.MAX_VALUE) { 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If the only work remaining are local ends at the end of the 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * block, stop here. Those are implied anyway. 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (next == codeSize 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project && nextAddrL == Integer.MAX_VALUE 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project && nextAddrP == Integer.MAX_VALUE) { 260f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein break; 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (next == nextAddrP) { 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Combined advance PC + position entry 265f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein emitPosition(sortedPositions.get(curPositionIdx++)); 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project emitAdvancePc(next - address); 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project emitEndSequence(); 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return output.toByteArray(); 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Emits all local variable activity that occurs at the current 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@link #address} starting at the given index into {@code 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * locals} and including all subsequent activity at the same 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * address. 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 282f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein * @param curLocalIdx Current index in locals 283f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein * @return new value for {@code curLocalIdx} 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 286f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein private int emitLocalsAtAddress(int curLocalIdx) 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws IOException { 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sz = locals.size(); 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // TODO: Don't emit ends implied by starts. 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 292f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein while ((curLocalIdx < sz) 293f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein && (locals.get(curLocalIdx).getAddress() == address)) { 294f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein LocalList.Entry entry = locals.get(curLocalIdx++); 295f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein int reg = entry.getRegister(); 296f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein LocalList.Entry prevEntry = lastEntryForReg[reg]; 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 298f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein if (entry == prevEntry) { 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Here we ignore locals entries for parameters, 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * which have already been represented and placed in the 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * lastEntryForReg array. 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 305f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein } 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // At this point we have a new entry one way or another. 308f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein lastEntryForReg[reg] = entry; 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 310f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein if (entry.isStart()) { 311f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein if ((prevEntry != null) && entry.matches(prevEntry)) { 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The previous local in this register has the same 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * name and type as the one being introduced now, so 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * use the more efficient "restart" form. 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 317f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein if (prevEntry.isStart()) { 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We should never be handed a start when a 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a matching local is already active. 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new RuntimeException("shouldn't happen"); 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 324f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein emitLocalRestart(entry); 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 326f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein emitLocalStart(entry); 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Only emit a local end if it is *not* due to a direct 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * replacement. Direct replacements imply an end of the 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * previous local in the same register. 333f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein * 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TODO: Make sure the runtime can deal with implied 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * local ends from category-2 interactions, and when so, 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * also stop emitting local ends for those cases. 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 338f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein if (entry.getDisposition() 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project != LocalList.Disposition.END_REPLACED) { 340f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein emitLocalEnd(entry); 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 345f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein return curLocalIdx; 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 34999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Emits all positions that occur at the current {@code address} 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 351f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein * @param curPositionIdx Current index in sortedPositions 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param sortedPositions positions, sorted by ascending address 353f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein * @return new value for {@code curPositionIdx} 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 356f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein private int emitPositionsAtAddress(int curPositionIdx, 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayList<PositionList.Entry> sortedPositions) 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws IOException { 359f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein int positionsSz = sortedPositions.size(); 360f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein while ((curPositionIdx < positionsSz) 361f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein && (sortedPositions.get(curPositionIdx).getAddress() 362f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein == address)) { 363f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein emitPosition(sortedPositions.get(curPositionIdx++)); 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 365f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein return curPositionIdx; 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Emits the header sequence, which consists of LEB128-encoded initial 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * line number and string indicies for names of all non-"this" arguments. 371f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein * 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param sortedPositions positions, sorted by ascending address 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param methodArgs local list entries for method argumens arguments, 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in left-to-right order omitting "this" 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void emitHeader(ArrayList<PositionList.Entry> sortedPositions, 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayList<LocalList.Entry> methodArgs) throws IOException { 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean annotate = (annotateTo != null) || (debugPrint != null); 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int mark = output.getCursor(); 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Start by initializing the line number register. 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (sortedPositions.size() > 0) { 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project PositionList.Entry entry = sortedPositions.get(0); 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project line = entry.getPosition().getLine(); 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 387dfc5e8e159e7df3efa47d553b7725be22839665dJesse Wilson output.writeUleb128(line); 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annotate) { 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project annotate(output.getCursor() - mark, "line_start: " + line); 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int curParam = getParamBase(); 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // paramTypes will not include 'this' 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StdTypeList paramTypes = desc.getParameterTypes(); 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int szParamTypes = paramTypes.size(); 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Initialize lastEntryForReg to have an initial 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * entry for the 'this' pointer. 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!isStatic) { 40341aecd0a6bfea1e9a6713014b2b3d56fec8c552cDan Bornstein for (LocalList.Entry arg : methodArgs) { 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (curParam == arg.getRegister()) { 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lastEntryForReg[curParam] = arg; 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project curParam++; 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Write out the number of parameter entries that will follow. 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mark = output.getCursor(); 414dfc5e8e159e7df3efa47d553b7725be22839665dJesse Wilson output.writeUleb128(szParamTypes); 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annotate) { 417f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein annotate(output.getCursor() - mark, 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String.format("parameters_size: %04x", szParamTypes)); 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Then emit the string indicies of all the method parameters. 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Note that 'this', if applicable, is excluded. 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < szParamTypes; i++) { 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Type pt = paramTypes.get(i); 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LocalList.Entry found = null; 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mark = output.getCursor(); 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 43141aecd0a6bfea1e9a6713014b2b3d56fec8c552cDan Bornstein for (LocalList.Entry arg : methodArgs) { 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (curParam == arg.getRegister()) { 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project found = arg; 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (arg.getSignature() != null) { 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parameters with signatures will be re-emitted 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in complete as LOCAL_START_EXTENDED's below. 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project emitStringIndex(null); 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project emitStringIndex(arg.getName()); 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lastEntryForReg[curParam] = arg; 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (found == null) { 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Emit a null symbol for "unnamed." This is common 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * for, e.g., synthesized methods and inner-class 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this$0 arguments. 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project emitStringIndex(null); 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annotate) { 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String parameterName 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project = (found == null || found.getSignature() != null) 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ? "<unnamed>" : found.getName().toHuman(); 463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project annotate(output.getCursor() - mark, 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "parameter " + parameterName + " " 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project + RegisterSpec.PREFIX + curParam); 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project curParam += pt.getCategory(); 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If anything emitted above has a type signature, emit it again as 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a LOCAL_RESTART_EXTENDED 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (LocalList.Entry arg : lastEntryForReg) { 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (arg == null) { 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 481333201833d506a3accdeac6ceb7caba8d4b95797Jesse Wilson CstString signature = arg.getSignature(); 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (signature != null) { 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project emitLocalStartExtended(arg); 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Builds a list of position entries, sorted by ascending address. 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return A sorted positions list 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private ArrayList<PositionList.Entry> buildSortedPositions() { 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sz = (positions == null) ? 0 : positions.size(); 496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayList<PositionList.Entry> result = new ArrayList(sz); 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < sz; i++) { 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.add(positions.get(i)); 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Sort ascending by address. 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Collections.sort (result, new Comparator<PositionList.Entry>() { 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int compare (PositionList.Entry a, PositionList.Entry b) { 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return a.getAddress() - b.getAddress(); 506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean equals (Object obj) { 509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return obj == this; 510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project }); 512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the register that begins the method's parameter range (including 517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the 'this' parameter for non-static methods). The range continues until 51899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code regSize} 519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return register as noted above 521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int getParamBase() { 523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return regSize 524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project - desc.getParameterTypes().getWordCount() - (isStatic? 0 : 1); 525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Extracts method arguments from a locals list. These will be collected 529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * from the input list and sorted by ascending register in the 530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * returned list. 531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 53299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return list of non-{@code this} method argument locals, 533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * sorted by ascending register 534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private ArrayList<LocalList.Entry> extractMethodArguments() { 536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayList<LocalList.Entry> result 537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project = new ArrayList(desc.getParameterTypes().size()); 538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int argBase = getParamBase(); 539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project BitSet seen = new BitSet(regSize - argBase); 540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sz = locals.size(); 541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < sz; i++) { 543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LocalList.Entry e = locals.get(i); 544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int reg = e.getRegister(); 545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (reg < argBase) { 547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // only the lowest-start-address entry is included. 551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (seen.get(reg - argBase)) { 552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seen.set(reg - argBase); 556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.add(e); 557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Sort by ascending register. 560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Collections.sort(result, new Comparator<LocalList.Entry>() { 561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int compare(LocalList.Entry a, LocalList.Entry b) { 562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return a.getRegister() - b.getRegister(); 563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean equals(Object obj) { 566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return obj == this; 567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project }); 569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a string representation of this LocalList entry that is 575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * appropriate for emitting as an annotation. 576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 57799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param e {@code non-null;} entry 57899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} annotation string 579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private String entryAnnotationString(LocalList.Entry e) { 581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringBuilder sb = new StringBuilder(); 582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(RegisterSpec.PREFIX); 584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(e.getRegister()); 585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(' '); 586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 587333201833d506a3accdeac6ceb7caba8d4b95797Jesse Wilson CstString name = e.getName(); 588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == null) { 589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append("null"); 590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(name.toHuman()); 592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(' '); 594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CstType type = e.getType(); 596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (type == null) { 597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append("null"); 598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(type.toHuman()); 600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 602333201833d506a3accdeac6ceb7caba8d4b95797Jesse Wilson CstString signature = e.getSignature(); 603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (signature != null) { 605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(' '); 606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(signature.toHuman()); 607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sb.toString(); 610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Emits a {@link DebugInfoConstants#DBG_RESTART_LOCAL DBG_RESTART_LOCAL} 614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * sequence. 615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param entry entry associated with this restart 617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void emitLocalRestart(LocalList.Entry entry) 620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws IOException { 621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int mark = output.getCursor(); 623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project output.writeByte(DBG_RESTART_LOCAL); 625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project emitUnsignedLeb128(entry.getRegister()); 626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annotateTo != null || debugPrint != null) { 628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project annotate(output.getCursor() - mark, 629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String.format("%04x: +local restart %s", 630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project address, entryAnnotationString(entry))); 631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (DEBUG) { 634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.err.println("emit local restart"); 635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Emits a string index as an unsigned LEB128. The actual value written 640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is shifted by 1, so that the '0' value is reserved for "null". The 641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * null symbol is used in some cases by the parameter name list 642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * at the beginning of the sequence. 643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 64499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param string {@code null-ok;} string to emit 645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 647333201833d506a3accdeac6ceb7caba8d4b95797Jesse Wilson private void emitStringIndex(CstString string) throws IOException { 648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((string == null) || (file == null)) { 649dfc5e8e159e7df3efa47d553b7725be22839665dJesse Wilson output.writeUleb128(0); 650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 651dfc5e8e159e7df3efa47d553b7725be22839665dJesse Wilson output.writeUleb128( 652dfc5e8e159e7df3efa47d553b7725be22839665dJesse Wilson 1 + file.getStringIds().indexOf(string)); 653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (DEBUG) { 656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.err.printf("Emit string %s\n", 657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project string == null ? "<null>" : string.toQuoted()); 658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Emits a type index as an unsigned LEB128. The actual value written 663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is shifted by 1, so that the '0' value is reserved for "null". 664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 66599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param type {@code null-ok;} type to emit 666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void emitTypeIndex(CstType type) throws IOException { 669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((type == null) || (file == null)) { 670dfc5e8e159e7df3efa47d553b7725be22839665dJesse Wilson output.writeUleb128(0); 671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 672dfc5e8e159e7df3efa47d553b7725be22839665dJesse Wilson output.writeUleb128( 673dfc5e8e159e7df3efa47d553b7725be22839665dJesse Wilson 1 + file.getTypeIds().indexOf(type)); 674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (DEBUG) { 677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.err.printf("Emit type %s\n", 678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type == null ? "<null>" : type.toHuman()); 679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Emits a {@link DebugInfoConstants#DBG_START_LOCAL DBG_START_LOCAL} or 684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@link DebugInfoConstants#DBG_START_LOCAL_EXTENDED 685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * DBG_START_LOCAL_EXTENDED} sequence. 686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param entry entry to emit 688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void emitLocalStart(LocalList.Entry entry) 691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws IOException { 692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (entry.getSignature() != null) { 694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project emitLocalStartExtended(entry); 695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int mark = output.getCursor(); 699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project output.writeByte(DBG_START_LOCAL); 701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project emitUnsignedLeb128(entry.getRegister()); 703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project emitStringIndex(entry.getName()); 704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project emitTypeIndex(entry.getType()); 705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annotateTo != null || debugPrint != null) { 707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project annotate(output.getCursor() - mark, 708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String.format("%04x: +local %s", address, 709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project entryAnnotationString(entry))); 710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (DEBUG) { 713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.err.println("emit local start"); 714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Emits a {@link DebugInfoConstants#DBG_START_LOCAL_EXTENDED 719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * DBG_START_LOCAL_EXTENDED} sequence. 720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param entry entry to emit 722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void emitLocalStartExtended(LocalList.Entry entry) 725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws IOException { 726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int mark = output.getCursor(); 728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project output.writeByte(DBG_START_LOCAL_EXTENDED); 730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project emitUnsignedLeb128(entry.getRegister()); 732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project emitStringIndex(entry.getName()); 733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project emitTypeIndex(entry.getType()); 734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project emitStringIndex(entry.getSignature()); 735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annotateTo != null || debugPrint != null) { 737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project annotate(output.getCursor() - mark, 738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String.format("%04x: +localx %s", address, 739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project entryAnnotationString(entry))); 740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (DEBUG) { 743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.err.println("emit local start"); 744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Emits a {@link DebugInfoConstants#DBG_END_LOCAL DBG_END_LOCAL} sequence. 749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 75099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param entry {@code entry non-null;} entry associated with end. 751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void emitLocalEnd(LocalList.Entry entry) 754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws IOException { 755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int mark = output.getCursor(); 757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project output.writeByte(DBG_END_LOCAL); 759dfc5e8e159e7df3efa47d553b7725be22839665dJesse Wilson output.writeUleb128(entry.getRegister()); 760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annotateTo != null || debugPrint != null) { 762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project annotate(output.getCursor() - mark, 763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String.format("%04x: -local %s", address, 764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project entryAnnotationString(entry))); 765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (DEBUG) { 768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.err.println("emit local end"); 769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Emits the necessary byte sequences to emit the given position table 774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * entry. This will typically be a single special opcode, although 775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * it may also require DBG_ADVANCE_PC or DBG_ADVANCE_LINE. 776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param entry position entry to emit. 778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void emitPosition(PositionList.Entry entry) 781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws IOException { 782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SourcePosition pos = entry.getPosition(); 784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int newLine = pos.getLine(); 785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int newAddress = entry.getAddress(); 786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int opcode; 788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int deltaLines = newLine - line; 790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int deltaAddress = newAddress - address; 791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (deltaAddress < 0) { 793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new RuntimeException( 794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "Position entries must be in ascending address order"); 795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((deltaLines < DBG_LINE_BASE) 798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project || (deltaLines > (DBG_LINE_BASE + DBG_LINE_RANGE -1))) { 799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project emitAdvanceLine(deltaLines); 800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project deltaLines = 0; 801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project opcode = computeOpcode (deltaLines, deltaAddress); 804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((opcode & ~0xff) > 0) { 806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project emitAdvancePc(deltaAddress); 807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project deltaAddress = 0; 808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project opcode = computeOpcode (deltaLines, deltaAddress); 809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((opcode & ~0xff) > 0) { 811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project emitAdvanceLine(deltaLines); 812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project deltaLines = 0; 813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project opcode = computeOpcode (deltaLines, deltaAddress); 814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project output.writeByte(opcode); 818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project line += deltaLines; 820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project address += deltaAddress; 821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annotateTo != null || debugPrint != null) { 823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project annotate(1, 824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String.format("%04x: line %d", address, line)); 825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Computes a special opcode that will encode the given position change. 830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If the return value is > 0xff, then the request cannot be fulfilled. 831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Essentially the same as described in "DWARF Debugging Format Version 3" 832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * section 6.2.5.1. 833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 83499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param deltaLines {@code >= DBG_LINE_BASE, <= DBG_LINE_BASE + 83599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * DBG_LINE_RANGE;} the line change to encode 83699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param deltaAddress {@code >= 0;} the address change to encode 83799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code <= 0xff} if in range, otherwise parameters are out 83899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * of range 839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static int computeOpcode(int deltaLines, int deltaAddress) { 841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (deltaLines < DBG_LINE_BASE 842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project || deltaLines > (DBG_LINE_BASE + DBG_LINE_RANGE -1)) { 843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 844f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein throw new RuntimeException("Parameter out of range"); 845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (deltaLines - DBG_LINE_BASE) 848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project + (DBG_LINE_RANGE * deltaAddress) + DBG_FIRST_SPECIAL; 849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Emits an {@link DebugInfoConstants#DBG_ADVANCE_LINE DBG_ADVANCE_LINE} 853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * sequence. 854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param deltaLines amount to change line number register by 856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void emitAdvanceLine(int deltaLines) throws IOException { 859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int mark = output.getCursor(); 860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project output.writeByte(DBG_ADVANCE_LINE); 862dfc5e8e159e7df3efa47d553b7725be22839665dJesse Wilson output.writeSleb128(deltaLines); 863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project line += deltaLines; 864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annotateTo != null || debugPrint != null) { 866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project annotate(output.getCursor() - mark, 867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String.format("line = %d", line)); 868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (DEBUG) { 871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.err.printf("Emitting advance_line for %d\n", deltaLines); 872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 876f58a5f30d1f0613e9e2dd3a24e6057f970258daeDan Bornstein * Emits an {@link DebugInfoConstants#DBG_ADVANCE_PC DBG_ADVANCE_PC} 877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * sequence. 878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 87999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param deltaAddress {@code >= 0;} amount to change program counter by 880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void emitAdvancePc(int deltaAddress) throws IOException { 883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int mark = output.getCursor(); 884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project output.writeByte(DBG_ADVANCE_PC); 886dfc5e8e159e7df3efa47d553b7725be22839665dJesse Wilson output.writeUleb128(deltaAddress); 887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project address += deltaAddress; 888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annotateTo != null || debugPrint != null) { 890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project annotate(output.getCursor() - mark, 891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String.format("%04x: advance pc", address)); 892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (DEBUG) { 895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.err.printf("Emitting advance_pc for %d\n", deltaAddress); 896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Emits an unsigned LEB128 value. 901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 90299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param n {@code >= 0;} value to emit. Note that, although this can 90399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * represent integers larger than Integer.MAX_VALUE, we currently don't 90499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * allow that. 905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void emitUnsignedLeb128(int n) throws IOException { 908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // We'll never need the top end of the unsigned range anyway. 909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (n < 0) { 910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new RuntimeException( 911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "Signed value where unsigned required: " + n); 912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 914dfc5e8e159e7df3efa47d553b7725be22839665dJesse Wilson output.writeUleb128(n); 915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Emits the {@link DebugInfoConstants#DBG_END_SEQUENCE DBG_END_SEQUENCE} 919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * bytecode. 920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void emitEndSequence() { 922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project output.writeByte(DBG_END_SEQUENCE); 923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annotateTo != null || debugPrint != null) { 925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project annotate(1, "end sequence"); 926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 929