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