|
35 | 35 | import java.io.IOException;
|
36 | 36 | import java.util.ArrayList;
|
37 | 37 | import java.util.Collections;
|
38 |
| -import java.util.HashMap; |
39 | 38 | import java.util.HashSet;
|
40 | 39 | import java.util.LinkedList;
|
41 | 40 | import java.util.List;
|
42 |
| -import java.util.Map; |
43 | 41 | import java.util.Set;
|
| 42 | +import java.util.TreeMap; |
| 43 | +import java.util.concurrent.atomic.AtomicReference; |
44 | 44 |
|
45 | 45 | import org.jf.dexlib2.analysis.ClassPath;
|
46 | 46 | import org.jf.dexlib2.analysis.ClassPathResolver;
|
@@ -140,7 +140,7 @@ public class DexBody {
|
140 | 140 | // registers
|
141 | 141 | protected Local[] registerLocals;
|
142 | 142 | protected Local storeResultLocal;
|
143 |
| - protected Map<Integer, DexlibAbstractInstruction> instructionAtAddress; |
| 143 | + protected TreeMap<Integer, DexlibAbstractInstruction> instructionAtAddress; |
144 | 144 |
|
145 | 145 | protected List<DeferableInstruction> deferredInstructions;
|
146 | 146 | protected Set<RetypeableInstruction> instructionsToRetype;
|
@@ -263,7 +263,9 @@ protected DexBody(DexEntry<? extends DexFile> dexFile, Method method, RefType de
|
263 | 263 | }
|
264 | 264 |
|
265 | 265 | instructions = new ArrayList<DexlibAbstractInstruction>();
|
266 |
| - instructionAtAddress = new HashMap<Integer, DexlibAbstractInstruction>(); |
| 266 | + |
| 267 | + // Use descending order |
| 268 | + instructionAtAddress = new TreeMap<Integer, DexlibAbstractInstruction>(); |
267 | 269 | localDebugs = ArrayListMultimap.create();
|
268 | 270 | takenLocalNames = new HashSet<String>();
|
269 | 271 |
|
@@ -446,27 +448,27 @@ public Local getStoreResultLocal() {
|
446 | 448 | * if address is not part of this body.
|
447 | 449 | */
|
448 | 450 | public DexlibAbstractInstruction instructionAtAddress(int address) {
|
449 |
| - DexlibAbstractInstruction i = null; |
450 |
| - while (i == null && address >= 0) { |
451 |
| - // catch addresses can be in the middlde of last instruction. Ex. in |
452 |
| - // com.letang.ldzja.en.apk: |
453 |
| - // |
454 |
| - // 042c46: 7020 2a15 0100 |008f: invoke-direct {v1, v0}, |
455 |
| - // Ljavax/mi... |
456 |
| - // 042c4c: 2701 |0092: throw v1 |
457 |
| - // catches : 4 |
458 |
| - // <any> -> 0x0065 |
459 |
| - // 0x0069 - 0x0093 |
460 |
| - // |
461 |
| - // SA, 14.05.2014: We originally scanned only two code units back. |
462 |
| - // This is not sufficient |
463 |
| - // if we e.g., have a wide constant and the line number in the debug |
464 |
| - // sections points to |
465 |
| - // some address the middle. |
466 |
| - i = instructionAtAddress.get(address); |
467 |
| - address--; |
| 451 | + |
| 452 | + // catch addresses can be in the middlde of last instruction. Ex. in |
| 453 | + // com.letang.ldzja.en.apk: |
| 454 | + // |
| 455 | + // 042c46: 7020 2a15 0100 |008f: invoke-direct {v1, v0}, |
| 456 | + // Ljavax/mi... |
| 457 | + // 042c4c: 2701 |0092: throw v1 |
| 458 | + // catches : 4 |
| 459 | + // <any> -> 0x0065 |
| 460 | + // 0x0069 - 0x0093 |
| 461 | + // |
| 462 | + // SA, 14.05.2014: We originally scanned only two code units back. |
| 463 | + // This is not sufficient |
| 464 | + // if we e.g., have a wide constant and the line number in the debug |
| 465 | + // sections points to |
| 466 | + // some address the middle. |
| 467 | + Integer key = instructionAtAddress.floorKey(address); |
| 468 | + if (key == null) { |
| 469 | + return null; |
468 | 470 | }
|
469 |
| - return i; |
| 471 | + return instructionAtAddress.get(key); |
470 | 472 | }
|
471 | 473 |
|
472 | 474 | /**
|
|
0 commit comments