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.DalvCode; 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.dex.code.DalvInsnList; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.dex.code.LocalList; 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.dex.code.PositionList; 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstMethodRef; 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.AnnotatedOutput; 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.PrintWriter; 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class DebugInfoItem extends OffsettedItem { 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** the required alignment for instances of this class */ 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final int ALIGNMENT = 1; 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final boolean ENABLE_ENCODER_SELF_CHECK = false; 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} the code this item represents */ 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final DalvCode code; 36de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private byte[] encoded; 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final boolean isStatic; 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final CstMethodRef ref; 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public DebugInfoItem(DalvCode code, boolean isStatic, CstMethodRef ref) { 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // We don't know the write size yet. 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project super (ALIGNMENT, -1); 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (code == null) { 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("code == null"); 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.code = code; 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.isStatic = isStatic; 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.ref = ref; 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public ItemType itemType() { 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ItemType.TYPE_DEBUG_INFO_ITEM; 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void addContents(DexFile file) { 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // No contents to add. 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected void place0(Section addedTo, int offset) { 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Encode the data and note the size. 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project encoded = encode(addedTo.getFile(), null, null, null, false); 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setWriteSize(encoded.length); 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (RuntimeException ex) { 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw ExceptionWithContext.withContext(ex, 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "...while placing debug info for " + ref.toHuman()); 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 80de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String toHuman() { 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new RuntimeException("unsupported"); 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Writes annotations for the elements of this list, as 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * zero-length. This is meant to be used for dumping this instance 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * directly after a code dump (with the real local list actually 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * existing elsewhere in the output). 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 9399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param file {@code non-null;} the file to use for referencing other sections 9499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param out {@code non-null;} where to annotate to 9599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param prefix {@code null-ok;} prefix to attach to each line of output 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void annotateTo(DexFile file, AnnotatedOutput out, String prefix) { 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project encode(file, prefix, null, out, false); 99de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro } 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Does a human-friendly dump of this instance. 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param out {@code non-null;} where to dump 10599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param prefix {@code non-null;} prefix to attach to each line of output 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void debugPrint(PrintWriter out, String prefix) { 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project encode(null, prefix, out, null, false); 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected void writeTo0(DexFile file, AnnotatedOutput out) { 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (out.annotates()) { 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Re-run the encoder to generate the annotations, 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * but write the bits from the original encode 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.annotate(offsetString() + " debug info"); 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project encode(file, null, null, out, true); 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.write(encoded); 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Performs debug info encoding. 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 13099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param file {@code null-ok;} file to refer to during encoding 13199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param prefix {@code null-ok;} prefix to attach to each line of output 13299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param debugPrint {@code null-ok;} if specified, an alternate output for 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * annotations 13499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param out {@code null-ok;} if specified, where annotations should go 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param consume whether to claim to have consumed output for 13699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code out} 13799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the encoded array 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private byte[] encode(DexFile file, String prefix, PrintWriter debugPrint, 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AnnotatedOutput out, boolean consume) { 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] result = encode0(file, prefix, debugPrint, out, consume); 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ENABLE_ENCODER_SELF_CHECK && (file != null)) { 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DebugInfoDecoder.validateEncode(result, file, ref, code, 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project isStatic); 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (RuntimeException ex) { 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Reconvert, annotating to System.err. 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project encode0(file, "", new PrintWriter(System.err, true), null, 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project false); 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw ex; 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper for {@link #encode} to do most of the work. 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 16199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param file {@code null-ok;} file to refer to during encoding 16299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param prefix {@code null-ok;} prefix to attach to each line of output 16399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param debugPrint {@code null-ok;} if specified, an alternate output for 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * annotations 16599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param out {@code null-ok;} if specified, where annotations should go 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param consume whether to claim to have consumed output for 16799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code out} 16899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the encoded array 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private byte[] encode0(DexFile file, String prefix, PrintWriter debugPrint, 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AnnotatedOutput out, boolean consume) { 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project PositionList positions = code.getPositions(); 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LocalList locals = code.getLocals(); 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DalvInsnList insns = code.getInsns(); 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int codeSize = insns.codeSize(); 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int regSize = insns.getRegistersSize(); 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DebugInfoEncoder encoder = 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new DebugInfoEncoder(positions, locals, 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project file, codeSize, regSize, isStatic, ref); 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] result; 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((debugPrint == null) && (out == null)) { 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = encoder.convert(); 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = encoder.convertAndAnnotate(prefix, debugPrint, out, 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project consume); 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 194