summaryrefslogtreecommitdiffstats
path: root/dex/src/main/java/com/android/dex/Dex.java
diff options
context:
space:
mode:
Diffstat (limited to 'dex/src/main/java/com/android/dex/Dex.java')
-rw-r--r--dex/src/main/java/com/android/dex/Dex.java109
1 files changed, 76 insertions, 33 deletions
diff --git a/dex/src/main/java/com/android/dex/Dex.java b/dex/src/main/java/com/android/dex/Dex.java
index e6bee6847..29cd30ea7 100644
--- a/dex/src/main/java/com/android/dex/Dex.java
+++ b/dex/src/main/java/com/android/dex/Dex.java
@@ -16,9 +16,12 @@
package com.android.dex;
+import com.android.dex.Code.CatchHandler;
+import com.android.dex.Code.Try;
import com.android.dex.util.ByteInput;
import com.android.dex.util.ByteOutput;
import com.android.dex.util.FileUtils;
+
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
@@ -546,41 +549,74 @@ public final class Dex {
int debugInfoOffset = readInt();
int instructionsSize = readInt();
short[] instructions = readShortArray(instructionsSize);
- Code.Try[] tries = new Code.Try[triesSize];
- Code.CatchHandler[] catchHandlers = new Code.CatchHandler[0];
+ Try[] tries;
+ CatchHandler[] catchHandlers;
if (triesSize > 0) {
- if (instructions.length % 2 == 1) {
- readShort(); // padding
- }
-
- for (int i = 0; i < triesSize; i++) {
- int startAddress = readInt();
- int instructionCount = readUnsignedShort();
- int handlerOffset = readUnsignedShort();
- tries[i] = new Code.Try(startAddress, instructionCount, handlerOffset);
- }
-
- int catchHandlersSize = readUleb128();
- catchHandlers = new Code.CatchHandler[catchHandlersSize];
- for (int i = 0; i < catchHandlersSize; i++) {
- catchHandlers[i] = readCatchHandler();
- }
- }
- return new Code(registersSize, insSize, outsSize, debugInfoOffset, instructions,
- tries, catchHandlers);
- }
-
- private Code.CatchHandler readCatchHandler() {
- int size = readSleb128();
- int handlersCount = Math.abs(size);
- int[] typeIndexes = new int[handlersCount];
- int[] addresses = new int[handlersCount];
- for (int i = 0; i < handlersCount; i++) {
- typeIndexes[i] = readUleb128();
- addresses[i] = readUleb128();
+ if (instructions.length % 2 == 1) {
+ readShort(); // padding
+ }
+
+ /*
+ * We can't read the tries until we've read the catch handlers.
+ * Unfortunately they're in the opposite order in the dex file
+ * so we need to read them out-of-order.
+ */
+ Section triesSection = open(data.position());
+ skip(triesSize * SizeOf.TRY_ITEM);
+ catchHandlers = readCatchHandlers();
+ tries = triesSection.readTries(triesSize, catchHandlers);
+ } else {
+ tries = new Try[0];
+ catchHandlers = new CatchHandler[0];
+ }
+ return new Code(registersSize, insSize, outsSize, debugInfoOffset, instructions,
+ tries, catchHandlers);
+ }
+
+ private CatchHandler[] readCatchHandlers() {
+ int baseOffset = data.position();
+ int catchHandlersSize = readUleb128();
+ CatchHandler[] result = new CatchHandler[catchHandlersSize];
+ for (int i = 0; i < catchHandlersSize; i++) {
+ int offset = data.position() - baseOffset;
+ result[i] = readCatchHandler(offset);
+ }
+ return result;
+ }
+
+ private Try[] readTries(int triesSize, CatchHandler[] catchHandlers) {
+ Try[] result = new Try[triesSize];
+ for (int i = 0; i < triesSize; i++) {
+ int startAddress = readInt();
+ int instructionCount = readUnsignedShort();
+ int handlerOffset = readUnsignedShort();
+ int catchHandlerIndex = findCatchHandlerIndex(catchHandlers, handlerOffset);
+ result[i] = new Try(startAddress, instructionCount, catchHandlerIndex);
+ }
+ return result;
+ }
+
+ private int findCatchHandlerIndex(CatchHandler[] catchHandlers, int offset) {
+ for (int i = 0; i < catchHandlers.length; i++) {
+ CatchHandler catchHandler = catchHandlers[i];
+ if (catchHandler.getOffset() == offset) {
+ return i;
}
- int catchAllAddress = size <= 0 ? readUleb128() : -1;
- return new Code.CatchHandler(typeIndexes, addresses, catchAllAddress);
+ }
+ throw new IllegalArgumentException();
+ }
+
+ private CatchHandler readCatchHandler(int offset) {
+ int size = readSleb128();
+ int handlersCount = Math.abs(size);
+ int[] typeIndexes = new int[handlersCount];
+ int[] addresses = new int[handlersCount];
+ for (int i = 0; i < handlersCount; i++) {
+ typeIndexes[i] = readUleb128();
+ addresses[i] = readUleb128();
+ }
+ int catchAllAddress = size <= 0 ? readUleb128() : -1;
+ return new CatchHandler(typeIndexes, addresses, catchAllAddress, offset);
}
private ClassData readClassData() {
@@ -643,6 +679,13 @@ public final class Dex {
return new EncodedValue(getBytesFrom(start));
}
+ public void skip(int count) {
+ if (count < 0) {
+ throw new IllegalArgumentException();
+ }
+ data.position(data.position() + count);
+ }
+
/**
* Skips bytes until the position is aligned to a multiple of 4.
*/