aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gruver <bgruv@google.com>2016-11-06 14:25:25 -0800
committerBen Gruver <bgruv@google.com>2016-11-06 14:25:25 -0800
commit5e387e59311b0115ce769dea93c787076c5d7d82 (patch)
tree061b9f04aacb3592537cc960c954eabebe7484c3
parenta0ccd94bf9c653107629ea3d94dd6db9bf94c0d9 (diff)
downloadsmali-5e387e59311b0115ce769dea93c787076c5d7d82.tar.gz
Add better error message for when instruction offset is out of range
-rw-r--r--dexlib2/src/main/java/org/jf/dexlib2/builder/BuilderOffsetInstruction.java14
-rw-r--r--dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java209
-rw-r--r--dexlib2/src/main/java/org/jf/dexlib2/writer/MethodSection.java1
-rw-r--r--dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderMethodPool.java4
-rw-r--r--dexlib2/src/main/java/org/jf/dexlib2/writer/pool/MethodPool.java4
5 files changed, 131 insertions, 101 deletions
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/builder/BuilderOffsetInstruction.java b/dexlib2/src/main/java/org/jf/dexlib2/builder/BuilderOffsetInstruction.java
index d75d7b67..27e43d5e 100644
--- a/dexlib2/src/main/java/org/jf/dexlib2/builder/BuilderOffsetInstruction.java
+++ b/dexlib2/src/main/java/org/jf/dexlib2/builder/BuilderOffsetInstruction.java
@@ -33,6 +33,7 @@ package org.jf.dexlib2.builder;
import org.jf.dexlib2.Opcode;
import org.jf.dexlib2.iface.instruction.OffsetInstruction;
+import org.jf.util.ExceptionWithContext;
import javax.annotation.Nonnull;
@@ -48,9 +49,16 @@ public abstract class BuilderOffsetInstruction extends BuilderInstruction implem
@Override public int getCodeOffset() {
int codeOffset = internalGetCodeOffset();
- if ((this.getCodeUnits() == 1 && (codeOffset < Byte.MIN_VALUE || codeOffset > Byte.MAX_VALUE)) ||
- (this.getCodeUnits() == 2 && (codeOffset < Short.MIN_VALUE || codeOffset > Short.MAX_VALUE))) {
- throw new IllegalStateException("Target is out of range");
+ if (this.getCodeUnits() == 1) {
+ if (codeOffset < Byte.MIN_VALUE || codeOffset > Byte.MAX_VALUE) {
+ throw new ExceptionWithContext("Invalid instruction offset: %d. " +
+ "Offset must be in [-128, 127]", codeOffset);
+ }
+ } else if (this.getCodeUnits() == 2) {
+ if (codeOffset < Short.MIN_VALUE || codeOffset > Short.MAX_VALUE) {
+ throw new ExceptionWithContext("Invalid instruction offset: %d. " +
+ "Offset must be in [-32768, 32767]", codeOffset);
+ }
}
return codeOffset;
}
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java
index 7109d361..00cce65d 100644
--- a/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java
+++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java
@@ -815,7 +815,14 @@ public abstract class DexWriter<
int debugItemOffset = writeDebugItem(offsetWriter, debugWriter,
classSection.getParameterNames(methodKey), debugItems);
- int codeItemOffset = writeCodeItem(codeWriter, ehBuf, methodKey, tryBlocks, instructions, debugItemOffset);
+ int codeItemOffset;
+ try {
+ codeItemOffset = writeCodeItem(
+ codeWriter, ehBuf, methodKey, tryBlocks, instructions, debugItemOffset);
+ } catch (RuntimeException ex) {
+ throw new ExceptionWithContext(ex, "Exception occurred while writing code_item for method %s",
+ methodSection.getMethodReference(methodKey));
+ }
if (codeItemOffset != -1) {
codeOffsets.add(new CodeItemOffset<MethodKey>(methodKey, codeItemOffset));
@@ -964,105 +971,111 @@ public abstract class DexWriter<
methodSection, protoSection);
writer.writeInt(codeUnitCount);
+ int codeOffset = 0;
for (Instruction instruction: instructions) {
- switch (instruction.getOpcode().format) {
- case Format10t:
- instructionWriter.write((Instruction10t)instruction);
- break;
- case Format10x:
- instructionWriter.write((Instruction10x)instruction);
- break;
- case Format11n:
- instructionWriter.write((Instruction11n)instruction);
- break;
- case Format11x:
- instructionWriter.write((Instruction11x)instruction);
- break;
- case Format12x:
- instructionWriter.write((Instruction12x)instruction);
- break;
- case Format20bc:
- instructionWriter.write((Instruction20bc)instruction);
- break;
- case Format20t:
- instructionWriter.write((Instruction20t)instruction);
- break;
- case Format21c:
- instructionWriter.write((Instruction21c)instruction);
- break;
- case Format21ih:
- instructionWriter.write((Instruction21ih)instruction);
- break;
- case Format21lh:
- instructionWriter.write((Instruction21lh)instruction);
- break;
- case Format21s:
- instructionWriter.write((Instruction21s)instruction);
- break;
- case Format21t:
- instructionWriter.write((Instruction21t)instruction);
- break;
- case Format22b:
- instructionWriter.write((Instruction22b)instruction);
- break;
- case Format22c:
- instructionWriter.write((Instruction22c)instruction);
- break;
- case Format22s:
- instructionWriter.write((Instruction22s)instruction);
- break;
- case Format22t:
- instructionWriter.write((Instruction22t)instruction);
- break;
- case Format22x:
- instructionWriter.write((Instruction22x)instruction);
- break;
- case Format23x:
- instructionWriter.write((Instruction23x)instruction);
- break;
- case Format30t:
- instructionWriter.write((Instruction30t)instruction);
- break;
- case Format31c:
- instructionWriter.write((Instruction31c)instruction);
- break;
- case Format31i:
- instructionWriter.write((Instruction31i)instruction);
- break;
- case Format31t:
- instructionWriter.write((Instruction31t)instruction);
- break;
- case Format32x:
- instructionWriter.write((Instruction32x)instruction);
- break;
- case Format35c:
- instructionWriter.write((Instruction35c)instruction);
- break;
- case Format3rc:
- instructionWriter.write((Instruction3rc)instruction);
- break;
- case Format45cc:
- instructionWriter.write((Instruction45cc) instruction);
- break;
- case Format4rcc:
- instructionWriter.write((Instruction4rcc) instruction);
- break;
- case Format51l:
- instructionWriter.write((Instruction51l)instruction);
- break;
- case ArrayPayload:
- instructionWriter.write((ArrayPayload)instruction);
- break;
- case PackedSwitchPayload:
- instructionWriter.write((PackedSwitchPayload)instruction);
- break;
- case SparseSwitchPayload:
- instructionWriter.write((SparseSwitchPayload)instruction);
- break;
- default:
- throw new ExceptionWithContext("Unsupported instruction format: %s",
- instruction.getOpcode().format);
+ try {
+ switch (instruction.getOpcode().format) {
+ case Format10t:
+ instructionWriter.write((Instruction10t)instruction);
+ break;
+ case Format10x:
+ instructionWriter.write((Instruction10x)instruction);
+ break;
+ case Format11n:
+ instructionWriter.write((Instruction11n)instruction);
+ break;
+ case Format11x:
+ instructionWriter.write((Instruction11x)instruction);
+ break;
+ case Format12x:
+ instructionWriter.write((Instruction12x)instruction);
+ break;
+ case Format20bc:
+ instructionWriter.write((Instruction20bc)instruction);
+ break;
+ case Format20t:
+ instructionWriter.write((Instruction20t)instruction);
+ break;
+ case Format21c:
+ instructionWriter.write((Instruction21c)instruction);
+ break;
+ case Format21ih:
+ instructionWriter.write((Instruction21ih)instruction);
+ break;
+ case Format21lh:
+ instructionWriter.write((Instruction21lh)instruction);
+ break;
+ case Format21s:
+ instructionWriter.write((Instruction21s)instruction);
+ break;
+ case Format21t:
+ instructionWriter.write((Instruction21t)instruction);
+ break;
+ case Format22b:
+ instructionWriter.write((Instruction22b)instruction);
+ break;
+ case Format22c:
+ instructionWriter.write((Instruction22c)instruction);
+ break;
+ case Format22s:
+ instructionWriter.write((Instruction22s)instruction);
+ break;
+ case Format22t:
+ instructionWriter.write((Instruction22t)instruction);
+ break;
+ case Format22x:
+ instructionWriter.write((Instruction22x)instruction);
+ break;
+ case Format23x:
+ instructionWriter.write((Instruction23x)instruction);
+ break;
+ case Format30t:
+ instructionWriter.write((Instruction30t)instruction);
+ break;
+ case Format31c:
+ instructionWriter.write((Instruction31c)instruction);
+ break;
+ case Format31i:
+ instructionWriter.write((Instruction31i)instruction);
+ break;
+ case Format31t:
+ instructionWriter.write((Instruction31t)instruction);
+ break;
+ case Format32x:
+ instructionWriter.write((Instruction32x)instruction);
+ break;
+ case Format35c:
+ instructionWriter.write((Instruction35c)instruction);
+ break;
+ case Format3rc:
+ instructionWriter.write((Instruction3rc)instruction);
+ break;
+ case Format45cc:
+ instructionWriter.write((Instruction45cc)instruction);
+ break;
+ case Format4rcc:
+ instructionWriter.write((Instruction4rcc)instruction);
+ break;
+ case Format51l:
+ instructionWriter.write((Instruction51l)instruction);
+ break;
+ case ArrayPayload:
+ instructionWriter.write((ArrayPayload)instruction);
+ break;
+ case PackedSwitchPayload:
+ instructionWriter.write((PackedSwitchPayload)instruction);
+ break;
+ case SparseSwitchPayload:
+ instructionWriter.write((SparseSwitchPayload)instruction);
+ break;
+ default:
+ throw new ExceptionWithContext("Unsupported instruction format: %s",
+ instruction.getOpcode().format);
+ }
+ } catch (RuntimeException ex) {
+ throw new ExceptionWithContext(ex, "Error while writing instruction at code offset 0x%x", codeOffset);
}
+ codeOffset += instruction.getCodeUnits();
}
if (tryBlocks.size() > 0) {
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/MethodSection.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/MethodSection.java
index 32e6d6bf..f31e84c8 100644
--- a/dexlib2/src/main/java/org/jf/dexlib2/writer/MethodSection.java
+++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/MethodSection.java
@@ -39,6 +39,7 @@ import javax.annotation.Nonnull;
public interface MethodSection<StringKey, TypeKey, ProtoRefKey extends MethodProtoReference,
MethodRefKey extends MethodReference, MethodKey>
extends IndexSection<MethodRefKey> {
+ @Nonnull MethodRefKey getMethodReference(@Nonnull MethodKey key);
@Nonnull TypeKey getDefiningClass(@Nonnull MethodRefKey key);
@Nonnull ProtoRefKey getPrototype(@Nonnull MethodRefKey key);
@Nonnull ProtoRefKey getPrototype(@Nonnull MethodKey key);
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderMethodPool.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderMethodPool.java
index e2c59369..7f937fdc 100644
--- a/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderMethodPool.java
+++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderMethodPool.java
@@ -71,6 +71,10 @@ class BuilderMethodPool extends BaseBuilderPool implements MethodSection<Builder
return internMethod(new MethodKey(definingClass, name, parameters, returnType));
}
+ @Nonnull @Override public BuilderMethodReference getMethodReference(@Nonnull BuilderMethod builderMethod) {
+ return builderMethod.methodReference;
+ }
+
@Nonnull @Override
public BuilderTypeReference getDefiningClass(@Nonnull BuilderMethodReference key) {
return key.definingClass;
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/MethodPool.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/MethodPool.java
index bb22458d..2801abd0 100644
--- a/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/MethodPool.java
+++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/MethodPool.java
@@ -53,6 +53,10 @@ public class MethodPool extends BaseIndexPool<MethodReference>
}
}
+ @Nonnull @Override public MethodReference getMethodReference(@Nonnull PoolMethod poolMethod) {
+ return poolMethod;
+ }
+
@Nonnull @Override public CharSequence getDefiningClass(@Nonnull MethodReference methodReference) {
return methodReference.getDefiningClass();
}