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