1/* 2 * [The "BSD licence"] 3 * Copyright (c) 2010 Ben Gruver (JesusFreke) 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29package org.jf.dexlib; 30 31import org.jf.dexlib.Debug.DebugInstructionIterator; 32import org.jf.dexlib.Debug.DebugOpcode; 33import org.jf.dexlib.Util.AnnotatedOutput; 34import org.jf.dexlib.Util.ByteArrayInput; 35import org.jf.dexlib.Util.Input; 36import org.jf.dexlib.Util.Leb128Utils; 37 38import java.util.ArrayList; 39import java.util.List; 40 41public class DebugInfoItem extends Item<DebugInfoItem> { 42 private int lineStart; 43 private StringIdItem[] parameterNames; 44 private byte[] encodedDebugInfo; 45 private Item[] referencedItems; 46 47 private CodeItem parent = null; 48 49 /** 50 * Creates a new uninitialized <code>DebugInfoInfo</code> 51 * @param dexFile The <code>DexFile</code> that this item belongs to 52 */ 53 public DebugInfoItem(DexFile dexFile) { 54 super(dexFile); 55 } 56 57 /** 58 * Creates a new <code>DebugInfoItem</code> with the given values 59 * @param dexFile The <code>DexFile</code> that this item belongs to 60 * @param lineStart the initial value for the line number register for the debug info machine 61 * @param parameterNames an array of the names of the associated method's parameters. The entire parameter 62 * can be null if no parameter info is available, or any element can be null to indicate no info for that parameter 63 * @param encodedDebugInfo the debug info, encoded as a byte array 64 * @param referencedItems an array of the items referenced by instructions, in order of occurance in the encoded 65 * debug info 66 */ 67 private DebugInfoItem(DexFile dexFile, 68 int lineStart, 69 StringIdItem[] parameterNames, 70 byte[] encodedDebugInfo, 71 Item[] referencedItems) { 72 super(dexFile); 73 this.lineStart = lineStart; 74 this.parameterNames = parameterNames; 75 this.encodedDebugInfo = encodedDebugInfo; 76 this.referencedItems = referencedItems; 77 } 78 79 /** 80 * Returns a new <code>DebugInfoItem</code> with the given values 81 * @param dexFile The <code>DexFile</code> that this item belongs to 82 * @param lineStart the initial value for the line number register for the debug info machine 83 * @param parameterNames an array of the names of the associated method's parameters. The entire parameter 84 * can be null if no parameter info is available, or any element can be null to indicate no info for that parameter 85 * @param encodedDebugInfo the debug info, encoded as a byte array 86 * @param referencedItems an array of the items referenced by instructions, in order of occurance in the encoded 87 * debug info 88 * @return a new <code>DebugInfoItem</code> with the given values 89 */ 90 public static DebugInfoItem internDebugInfoItem(DexFile dexFile, 91 int lineStart, 92 StringIdItem[] parameterNames, 93 byte[] encodedDebugInfo, 94 Item[] referencedItems) { 95 DebugInfoItem debugInfoItem = new DebugInfoItem(dexFile, lineStart, parameterNames, encodedDebugInfo, 96 referencedItems); 97 return dexFile.DebugInfoItemsSection.intern(debugInfoItem); 98 } 99 100 /** {@inheritDoc} */ 101 protected void readItem(Input in, ReadContext readContext) { 102 lineStart = in.readUnsignedLeb128(); 103 parameterNames = new StringIdItem[in.readUnsignedLeb128()]; 104 IndexedSection<StringIdItem> stringIdSection = dexFile.StringIdsSection; 105 for (int i=0; i<parameterNames.length; i++) { 106 parameterNames[i] = stringIdSection.getOptionalItemByIndex(in.readUnsignedLeb128() - 1); 107 } 108 109 int start = in.getCursor(); 110 final List<Item> referencedItemsList = new ArrayList<Item>(50); 111 DebugInstructionIterator.IterateInstructions(in, 112 new DebugInstructionIterator.ProcessRawDebugInstructionDelegate() { 113 @Override 114 public void ProcessStartLocal(int startDebugOffset, int length, int registerNum, int nameIndex, 115 int typeIndex, boolean registerIsSigned) { 116 if (nameIndex != -1) { 117 referencedItemsList.add(dexFile.StringIdsSection.getItemByIndex(nameIndex)); 118 } 119 if (typeIndex != -1) { 120 referencedItemsList.add(dexFile.TypeIdsSection.getItemByIndex(typeIndex)); 121 } 122 } 123 124 @Override 125 public void ProcessStartLocalExtended(int startDebugOffset, int length, int registerNume, 126 int nameIndex, int typeIndex, int signatureIndex, 127 boolean registerIsSigned) { 128 if (nameIndex != -1) { 129 referencedItemsList.add(dexFile.StringIdsSection.getItemByIndex(nameIndex)); 130 } 131 if (typeIndex != -1) { 132 referencedItemsList.add(dexFile.TypeIdsSection.getItemByIndex(typeIndex)); 133 } 134 if (signatureIndex != -1) { 135 referencedItemsList.add(dexFile.StringIdsSection.getItemByIndex(signatureIndex)); 136 } 137 } 138 139 @Override 140 public void ProcessSetFile(int startDebugOffset, int length, int nameIndex) { 141 if (nameIndex != -1) { 142 referencedItemsList.add(dexFile.StringIdsSection.getItemByIndex(nameIndex)); 143 } 144 } 145 }); 146 147 referencedItems = new Item[referencedItemsList.size()]; 148 referencedItemsList.toArray(referencedItems); 149 150 int length = in.getCursor() - start; 151 in.setCursor(start); 152 encodedDebugInfo = in.readBytes(length); 153 } 154 155 156 157 /** {@inheritDoc} */ 158 protected int placeItem(int offset) { 159 offset += Leb128Utils.unsignedLeb128Size(lineStart); 160 offset += Leb128Utils.unsignedLeb128Size(parameterNames.length); 161 for (StringIdItem parameterName: parameterNames) { 162 int indexp1; 163 if (parameterName == null) { 164 indexp1 = 0; 165 } else { 166 indexp1 = parameterName.getIndex() + 1; 167 } 168 offset += Leb128Utils.unsignedLeb128Size(indexp1); 169 } 170 171 //make a subclass so we can keep track of and access the computed length 172 class ProcessDebugInstructionDelegateWithLength extends 173 DebugInstructionIterator.ProcessRawDebugInstructionDelegate { 174 public int length = 0; 175 } 176 ProcessDebugInstructionDelegateWithLength pdidwl; 177 178 //final referencedItems = this.referencedItems; 179 180 DebugInstructionIterator.IterateInstructions(new ByteArrayInput(encodedDebugInfo), 181 pdidwl = new ProcessDebugInstructionDelegateWithLength() { 182 private int referencedItemsPosition = 0; 183 184 @Override 185 public void ProcessStaticOpcode(DebugOpcode opcode, int startDebugOffset, int length) { 186 this.length+=length; 187 } 188 189 @Override 190 public void ProcessStartLocal(int startDebugOffset, int length, int registerNum, int nameIndex, 191 int typeIndex, boolean registerIsSigned) { 192 this.length++; 193 if (dexFile.getPreserveSignedRegisters() && registerIsSigned) { 194 this.length += Leb128Utils.signedLeb128Size(registerNum); 195 } else { 196 this.length+=Leb128Utils.unsignedLeb128Size(registerNum); 197 } 198 if (nameIndex != -1) { 199 this.length+= 200 Leb128Utils.unsignedLeb128Size(referencedItems[referencedItemsPosition++].getIndex()+1); 201 } else { 202 this.length++; 203 } 204 if (typeIndex != -1) { 205 this.length+= 206 Leb128Utils.unsignedLeb128Size(referencedItems[referencedItemsPosition++].getIndex()+1); 207 } else { 208 this.length++; 209 } 210 211 } 212 213 @Override 214 public void ProcessStartLocalExtended(int startDebugOffset, int length, int registerNum, int nameIndex, 215 int typeIndex, int signatureIndex, 216 boolean registerIsSigned) { 217 this.length++; 218 if (dexFile.getPreserveSignedRegisters() && registerIsSigned) { 219 this.length += Leb128Utils.signedLeb128Size(registerNum); 220 } else { 221 this.length+=Leb128Utils.unsignedLeb128Size(registerNum); 222 } 223 if (nameIndex != -1) { 224 this.length+= 225 Leb128Utils.unsignedLeb128Size(referencedItems[referencedItemsPosition++].getIndex()+1); 226 } else { 227 this.length++; 228 } 229 if (typeIndex != -1) { 230 this.length+= 231 Leb128Utils.unsignedLeb128Size(referencedItems[referencedItemsPosition++].getIndex()+1); 232 } else { 233 this.length++; 234 } 235 if (signatureIndex != -1) { 236 this.length+= 237 Leb128Utils.unsignedLeb128Size(referencedItems[referencedItemsPosition++].getIndex()+1); 238 } else { 239 this.length++; 240 } 241 } 242 243 @Override 244 public void ProcessSetFile(int startDebugOffset, int length, int nameIndex) { 245 this.length++; 246 if (nameIndex != -1) { 247 this.length+= 248 Leb128Utils.unsignedLeb128Size(referencedItems[referencedItemsPosition++].getIndex()+1); 249 } else { 250 this.length++; 251 } 252 } 253 }); 254 return offset + pdidwl.length; 255 } 256 257 /** {@inheritDoc} */ 258 protected void writeItem(final AnnotatedOutput out) { 259 if (out.annotates()) { 260 writeItemWithAnnotations(out); 261 } else { 262 writeItemWithNoAnnotations(out); 263 } 264 } 265 266 /** 267 * Replaces the encoded debug info for this DebugInfoItem. It is expected that the new debug info is compatible 268 * with the existing information, i.e. lineStart, referencedItems, parameterNames 269 * @param encodedDebugInfo the new encoded debug info 270 */ 271 protected void setEncodedDebugInfo(byte[] encodedDebugInfo) { 272 //TODO: I would rather replace this method with some way of saying "The (code) instruction at address changed from A bytes to B bytes. Fixup the debug info accordingly" 273 274 this.encodedDebugInfo = encodedDebugInfo; 275 } 276 277 /** 278 * Helper method that writes the item, without writing annotations 279 * @param out the AnnotatedOutput object 280 */ 281 private void writeItemWithNoAnnotations(final AnnotatedOutput out) { 282 out.writeUnsignedLeb128(lineStart); 283 out.writeUnsignedLeb128(parameterNames.length); 284 for (StringIdItem parameterName: parameterNames) { 285 int indexp1; 286 if (parameterName == null) { 287 indexp1 = 0; 288 } else { 289 indexp1 = parameterName.getIndex() + 1; 290 } 291 out.writeUnsignedLeb128(indexp1); 292 } 293 294 DebugInstructionIterator.IterateInstructions(new ByteArrayInput(encodedDebugInfo), 295 new DebugInstructionIterator.ProcessRawDebugInstructionDelegate() { 296 private int referencedItemsPosition = 0; 297 298 @Override 299 public void ProcessStaticOpcode(DebugOpcode opcode, int startDebugOffset, int length) { 300 out.write(encodedDebugInfo, startDebugOffset, length); 301 } 302 303 @Override 304 public void ProcessStartLocal(int startDebugOffset, int length, int registerNum, int nameIndex, 305 int typeIndex, boolean registerIsSigned) { 306 out.writeByte(DebugOpcode.DBG_START_LOCAL.value); 307 if (dexFile.getPreserveSignedRegisters() && registerIsSigned) { 308 out.writeSignedLeb128(registerNum); 309 } else { 310 out.writeUnsignedLeb128(registerNum); 311 } 312 if (nameIndex != -1) { 313 out.writeUnsignedLeb128(referencedItems[referencedItemsPosition++].getIndex() + 1); 314 } else { 315 out.writeByte(0); 316 } 317 if (typeIndex != -1) { 318 out.writeUnsignedLeb128(referencedItems[referencedItemsPosition++].getIndex() + 1); 319 } else { 320 out.writeByte(0); 321 } 322 } 323 324 @Override 325 public void ProcessStartLocalExtended(int startDebugOffset, int length, int registerNum, int nameIndex, 326 int typeIndex, int signatureIndex, 327 boolean registerIsSigned) { 328 out.writeByte(DebugOpcode.DBG_START_LOCAL_EXTENDED.value); 329 if (dexFile.getPreserveSignedRegisters() && registerIsSigned) { 330 out.writeSignedLeb128(registerNum); 331 } else { 332 out.writeUnsignedLeb128(registerNum); 333 } 334 if (nameIndex != -1) { 335 out.writeUnsignedLeb128(referencedItems[referencedItemsPosition++].getIndex() + 1); 336 } else { 337 out.writeByte(0); 338 } 339 if (typeIndex != -1) { 340 out.writeUnsignedLeb128(referencedItems[referencedItemsPosition++].getIndex() + 1); 341 } else { 342 out.writeByte(0); 343 } 344 if (signatureIndex != -1) { 345 out.writeUnsignedLeb128(referencedItems[referencedItemsPosition++].getIndex() + 1); 346 } else { 347 out.writeByte(0); 348 } 349 } 350 351 @Override 352 public void ProcessSetFile(int startDebugOffset, int length, int nameIndex) { 353 out.writeByte(DebugOpcode.DBG_SET_FILE.value); 354 if (nameIndex != -1) { 355 out.writeUnsignedLeb128(referencedItems[referencedItemsPosition++].getIndex() + 1); 356 } else { 357 out.writeByte(0); 358 } 359 } 360 }); 361 } 362 363 /** 364 * Helper method that writes and annotates the item 365 * @param out the AnnotatedOutput object 366 */ 367 private void writeItemWithAnnotations(final AnnotatedOutput out) { 368 out.annotate(0, parent.getParent().method.getMethodString()); 369 out.annotate("line_start: 0x" + Integer.toHexString(lineStart) + " (" + lineStart + ")"); 370 out.writeUnsignedLeb128(lineStart); 371 out.annotate("parameters_size: 0x" + Integer.toHexString(parameterNames.length) + " (" + parameterNames.length 372 + ")"); 373 out.writeUnsignedLeb128(parameterNames.length); 374 int index = 0; 375 for (StringIdItem parameterName: parameterNames) { 376 int indexp1; 377 if (parameterName == null) { 378 out.annotate("[" + index++ +"] parameterName: "); 379 indexp1 = 0; 380 } else { 381 out.annotate("[" + index++ +"] parameterName: " + parameterName.getStringValue()); 382 indexp1 = parameterName.getIndex() + 1; 383 } 384 out.writeUnsignedLeb128(indexp1); 385 } 386 387 DebugInstructionIterator.IterateInstructions(new ByteArrayInput(encodedDebugInfo), 388 new DebugInstructionIterator.ProcessRawDebugInstructionDelegate() { 389 private int referencedItemsPosition = 0; 390 391 @Override 392 public void ProcessEndSequence(int startDebugOffset) { 393 out.annotate("DBG_END_SEQUENCE"); 394 out.writeByte(DebugOpcode.DBG_END_SEQUENCE.value); 395 } 396 397 @Override 398 public void ProcessAdvancePC(int startDebugOffset, int length, int addressDiff) { 399 out.annotate("DBG_ADVANCE_PC"); 400 out.writeByte(DebugOpcode.DBG_ADVANCE_PC.value); 401 out.indent(); 402 out.annotate("addr_diff: 0x" + Integer.toHexString(addressDiff) + " (" + addressDiff + ")"); 403 out.writeUnsignedLeb128(addressDiff); 404 out.deindent(); 405 } 406 407 @Override 408 public void ProcessAdvanceLine(int startDebugOffset, int length, int lineDiff) { 409 out.annotate("DBG_ADVANCE_LINE"); 410 out.writeByte(DebugOpcode.DBG_ADVANCE_LINE.value); 411 out.indent(); 412 out.annotate("line_diff: 0x" + Integer.toHexString(lineDiff) + " (" + lineDiff + ")"); 413 out.writeSignedLeb128(lineDiff); 414 out.deindent(); 415 } 416 417 @Override 418 public void ProcessStartLocal(int startDebugOffset, int length, int registerNum, int nameIndex, 419 int typeIndex, boolean registerIsSigned) { 420 out.annotate("DBG_START_LOCAL"); 421 out.writeByte(DebugOpcode.DBG_START_LOCAL.value); 422 out.indent(); 423 out.annotate("register_num: 0x" + Integer.toHexString(registerNum) + " (" + registerNum + ")"); 424 if (dexFile.getPreserveSignedRegisters() && registerIsSigned) { 425 out.writeSignedLeb128(registerNum); 426 } else { 427 out.writeUnsignedLeb128(registerNum); 428 } 429 if (nameIndex != -1) { 430 Item nameItem = referencedItems[referencedItemsPosition++]; 431 assert nameItem instanceof StringIdItem; 432 out.annotate("name: " + ((StringIdItem)nameItem).getStringValue()); 433 out.writeUnsignedLeb128(nameItem.getIndex() + 1); 434 } else { 435 out.annotate("name: "); 436 out.writeByte(0); 437 } 438 if (typeIndex != -1) { 439 Item typeItem = referencedItems[referencedItemsPosition++]; 440 assert typeItem instanceof TypeIdItem; 441 out.annotate("type: " + ((TypeIdItem)typeItem).getTypeDescriptor()); 442 out.writeUnsignedLeb128(typeItem.getIndex() + 1); 443 } else { 444 out.annotate("type: "); 445 out.writeByte(0); 446 } 447 out.deindent(); 448 } 449 450 @Override 451 public void ProcessStartLocalExtended(int startDebugOffset, int length, int registerNum, 452 int nameIndex, int typeIndex, int signatureIndex, 453 boolean registerIsSigned) { 454 out.annotate("DBG_START_LOCAL_EXTENDED"); 455 out.writeByte(DebugOpcode.DBG_START_LOCAL_EXTENDED.value); 456 out.indent(); 457 out.annotate("register_num: 0x" + Integer.toHexString(registerNum) + " (" + registerNum + ")"); 458 if (dexFile.getPreserveSignedRegisters() && registerIsSigned) { 459 out.writeSignedLeb128(registerNum); 460 } else { 461 out.writeUnsignedLeb128(registerNum); 462 } 463 if (nameIndex != -1) { 464 Item nameItem = referencedItems[referencedItemsPosition++]; 465 assert nameItem instanceof StringIdItem; 466 out.annotate("name: " + ((StringIdItem)nameItem).getStringValue()); 467 out.writeUnsignedLeb128(nameItem.getIndex() + 1); 468 } else { 469 out.annotate("name: "); 470 out.writeByte(0); 471 } 472 if (typeIndex != -1) { 473 Item typeItem = referencedItems[referencedItemsPosition++]; 474 assert typeItem instanceof TypeIdItem; 475 out.annotate("type: " + ((TypeIdItem)typeItem).getTypeDescriptor()); 476 out.writeUnsignedLeb128(typeItem.getIndex() + 1); 477 } else { 478 out.annotate("type: "); 479 out.writeByte(0); 480 } 481 if (signatureIndex != -1) { 482 Item signatureItem = referencedItems[referencedItemsPosition++]; 483 assert signatureItem instanceof StringIdItem; 484 out.annotate("signature: " + ((StringIdItem)signatureItem).getStringValue()); 485 out.writeUnsignedLeb128(signatureItem.getIndex() + 1); 486 } else { 487 out.annotate("signature: "); 488 out.writeByte(0); 489 } 490 out.deindent(); 491 } 492 493 @Override 494 public void ProcessEndLocal(int startDebugOffset, int length, int registerNum, 495 boolean registerIsSigned) { 496 out.annotate("DBG_END_LOCAL"); 497 out.writeByte(DebugOpcode.DBG_END_LOCAL.value); 498 out.annotate("register_num: 0x" + Integer.toHexString(registerNum) + " (" + registerNum + ")"); 499 if (registerIsSigned) { 500 out.writeSignedLeb128(registerNum); 501 } else { 502 out.writeUnsignedLeb128(registerNum); 503 } 504 } 505 506 @Override 507 public void ProcessRestartLocal(int startDebugOffset, int length, int registerNum, 508 boolean registerIsSigned) { 509 out.annotate("DBG_RESTART_LOCAL"); 510 out.writeByte(DebugOpcode.DBG_RESTART_LOCAL.value); 511 out.annotate("register_num: 0x" + Integer.toHexString(registerNum) + " (" + registerNum + ")"); 512 if (registerIsSigned) { 513 out.writeSignedLeb128(registerNum); 514 } else { 515 out.writeUnsignedLeb128(registerNum); 516 } 517 } 518 519 @Override 520 public void ProcessSetPrologueEnd(int startDebugOffset) { 521 out.annotate("DBG_SET_PROLOGUE_END"); 522 out.writeByte(DebugOpcode.DBG_SET_PROLOGUE_END.value); 523 } 524 525 @Override 526 public void ProcessSetEpilogueBegin(int startDebugOffset) { 527 out.annotate("DBG_SET_EPILOGUE_BEGIN"); 528 out.writeByte(DebugOpcode.DBG_SET_EPILOGUE_BEGIN.value); 529 } 530 531 @Override 532 public void ProcessSetFile(int startDebugOffset, int length, int nameIndex) { 533 out.annotate("DBG_SET_FILE"); 534 out.writeByte(DebugOpcode.DBG_SET_FILE.value); 535 if (nameIndex != -1) { 536 Item sourceItem = referencedItems[referencedItemsPosition++]; 537 assert sourceItem instanceof StringIdItem; 538 out.annotate("source_file: \"" + ((StringIdItem)sourceItem).getStringValue() + "\""); 539 out.writeUnsignedLeb128(sourceItem.getIndex() + 1); 540 } else { 541 out.annotate("source_file: "); 542 out.writeByte(0); 543 } 544 } 545 546 @Override 547 public void ProcessSpecialOpcode(int startDebugOffset, int debugOpcode, int lineDiff, 548 int addressDiff) { 549 out.annotate("DBG_SPECIAL_OPCODE: line_diff=0x" + Integer.toHexString(lineDiff) + "(" + 550 lineDiff +"),addressDiff=0x" + Integer.toHexString(addressDiff) + "(" + addressDiff + 551 ")"); 552 out.writeByte(debugOpcode); 553 } 554 }); 555 } 556 557 558 559 560 /** {@inheritDoc} */ 561 public ItemType getItemType() { 562 return ItemType.TYPE_DEBUG_INFO_ITEM; 563 } 564 565 /** {@inheritDoc} */ 566 public String getConciseIdentity() { 567 return "debug_info_item @0x" + Integer.toHexString(getOffset()); 568 } 569 570 /** {@inheritDoc} */ 571 public int compareTo(DebugInfoItem other) { 572 if (parent == null) { 573 if (other.parent == null) { 574 return 0; 575 } 576 return -1; 577 } 578 if (other.parent == null) { 579 return 1; 580 } 581 return parent.compareTo(other.parent); 582 } 583 584 /** 585 * Set the <code>CodeItem</code> that this <code>DebugInfoItem</code> is associated with 586 * @param codeItem the <code>CodeItem</code> that this <code>DebugInfoItem</code> is associated with 587 */ 588 protected void setParent(CodeItem codeItem) { 589 this.parent = codeItem; 590 } 591 592 /** 593 * @return the initial value for the line number register for the debug info machine 594 */ 595 public int getLineStart() { 596 return lineStart; 597 } 598 599 /** 600 * @return the debug info, encoded as a byte array 601 */ 602 public byte[] getEncodedDebugInfo() { 603 return encodedDebugInfo; 604 } 605 606 /** 607 * @return an array of the items referenced by instructions, in order of occurance in the encoded debug info 608 */ 609 public Item[] getReferencedItems() { 610 return referencedItems; 611 } 612 613 /** 614 * @return an array of the names of the associated method's parameters. The array can be null if no parameter info 615 * is available, or any element can be null to indicate no info for that parameter 616 */ 617 public StringIdItem[] getParameterNames() { 618 return parameterNames; 619 } 620} 621