From ffe82bdcb5c914b3a60b630c6d3abe6fc9229dec Mon Sep 17 00:00:00 2001 From: Ben Gruver Date: Sun, 7 Apr 2013 17:01:49 -0700 Subject: [PATCH] Fully remove the dependency on the old dexlib from baksmali --- baksmali/build.gradle | 1 - .../jf/baksmali/Adaptors/CatchMethodItem.java | 1 - .../Format/InstructionMethodItem.java | 6 +- .../UnresolvedOdexInstructionMethodItem.java | 6 - .../baksmali/Adaptors/MethodDefinition.java | 11 +- ...PostInstructionRegisterInfoMethodItem.java | 11 - .../PreInstructionRegisterInfoMethodItem.java | 13 - .../baksmali/Adaptors/RegisterFormatter.java | 5 +- .../main/java/org/jf/baksmali/baksmali.java | 2 +- .../main/java/org/jf/util/SparseIntArray.java | 268 ++++++++++++++++++ 10 files changed, 280 insertions(+), 44 deletions(-) create mode 100644 util/src/main/java/org/jf/util/SparseIntArray.java diff --git a/baksmali/build.gradle b/baksmali/build.gradle index da47f14b..3fc7b069 100644 --- a/baksmali/build.gradle +++ b/baksmali/build.gradle @@ -35,7 +35,6 @@ configurations { dependencies { compile project(':util') - compile project(':dexlib') compile project(':dexlib2') compile depends.commons_cli compile depends.guava diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/CatchMethodItem.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/CatchMethodItem.java index ca766558..a0c724c9 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/CatchMethodItem.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/CatchMethodItem.java @@ -29,7 +29,6 @@ package org.jf.baksmali.Adaptors; import org.jf.util.IndentingWriter; -import org.jf.dexlib.TypeIdItem; import java.io.IOException; diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItem.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItem.java index 3602f398..0eabeb03 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItem.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItem.java @@ -32,7 +32,6 @@ import org.jf.baksmali.Adaptors.MethodDefinition; import org.jf.baksmali.Adaptors.MethodItem; import org.jf.baksmali.Adaptors.ReferenceFormatter; import org.jf.baksmali.Renderers.LongRenderer; -import org.jf.dexlib.Code.Format.UnknownInstruction; import org.jf.dexlib2.VerificationError; import org.jf.dexlib2.iface.instruction.*; import org.jf.dexlib2.iface.instruction.formats.Instruction20bc; @@ -65,11 +64,12 @@ public class InstructionMethodItem extends MethodItem { writeTargetLabel(writer); return true; case Format10x: - if (instruction instanceof UnknownInstruction) { + // TODO: uncomment + /*if (instruction instanceof UnknownInstruction) { writer.write("#unknown opcode: 0x"); writer.printUnsignedLongAsHex(((UnknownInstruction) instruction).getOriginalOpcode() & 0xFFFF); writer.write('\n'); - } + }*/ writeOpcode(writer); return true; case Format11n: diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/UnresolvedOdexInstructionMethodItem.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/UnresolvedOdexInstructionMethodItem.java index e257ad63..ad805880 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/UnresolvedOdexInstructionMethodItem.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/UnresolvedOdexInstructionMethodItem.java @@ -28,12 +28,6 @@ package org.jf.baksmali.Adaptors.Format; -import org.jf.util.IndentingWriter; -import org.jf.dexlib.Code.Format.UnresolvedOdexInstruction; -import org.jf.dexlib.CodeItem; - -import java.io.IOException; - //TODO: uncomment /*public class UnresolvedOdexInstructionMethodItem extends InstructionMethodItem { public UnresolvedOdexInstructionMethodItem(CodeItem codeItem, int codeAddress, UnresolvedOdexInstruction instruction) { diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/MethodDefinition.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/MethodDefinition.java index 3ae0eac9..458baa22 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/MethodDefinition.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/MethodDefinition.java @@ -31,6 +31,7 @@ package org.jf.baksmali.Adaptors; import com.google.common.collect.ImmutableList; import org.jf.baksmali.Adaptors.Debug.DebugMethodItem; import org.jf.baksmali.Adaptors.Format.InstructionMethodItemFactory; +import org.jf.baksmali.baksmali; import org.jf.dexlib2.AccessFlags; import org.jf.dexlib2.Opcode; import org.jf.dexlib2.ReferenceType; @@ -40,11 +41,13 @@ import org.jf.dexlib2.iface.instruction.Instruction; import org.jf.dexlib2.iface.instruction.OffsetInstruction; import org.jf.dexlib2.iface.instruction.ReferenceInstruction; import org.jf.dexlib2.iface.reference.MethodReference; -import org.jf.dexlib2.util.*; -import org.jf.util.IndentingWriter; -import org.jf.baksmali.baksmali; +import org.jf.dexlib2.util.InstructionOffsetMap; +import org.jf.dexlib2.util.ReferenceUtil; +import org.jf.dexlib2.util.SyntheticAccessorResolver; +import org.jf.dexlib2.util.TypeUtils; import org.jf.util.ExceptionWithContext; -import org.jf.dexlib.Util.SparseIntArray; +import org.jf.util.IndentingWriter; +import org.jf.util.SparseIntArray; import javax.annotation.Nonnull; import java.io.IOException; diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/PostInstructionRegisterInfoMethodItem.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/PostInstructionRegisterInfoMethodItem.java index c067aa4a..70eb775c 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/PostInstructionRegisterInfoMethodItem.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/PostInstructionRegisterInfoMethodItem.java @@ -28,17 +28,6 @@ package org.jf.baksmali.Adaptors; -import org.jf.util.IndentingWriter; -import org.jf.baksmali.baksmali; -import org.jf.baksmali.main; -import org.jf.dexlib.ClassDataItem; -import org.jf.dexlib.Code.Analysis.AnalyzedInstruction; -import org.jf.dexlib.Code.Analysis.MethodAnalyzer; -import org.jf.dexlib.Code.Analysis.RegisterType; - -import java.io.IOException; -import java.util.BitSet; - //TODO: uncomment /*public class PostInstructionRegisterInfoMethodItem extends MethodItem { private final AnalyzedInstruction analyzedInstruction; diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/PreInstructionRegisterInfoMethodItem.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/PreInstructionRegisterInfoMethodItem.java index fa3c3d3c..cd6917a6 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/PreInstructionRegisterInfoMethodItem.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/PreInstructionRegisterInfoMethodItem.java @@ -28,19 +28,6 @@ package org.jf.baksmali.Adaptors; -import org.jf.util.IndentingWriter; -import org.jf.baksmali.baksmali; -import org.jf.baksmali.main; -import org.jf.dexlib.ClassDataItem; -import org.jf.dexlib.Code.Analysis.AnalyzedInstruction; -import org.jf.dexlib.Code.Analysis.MethodAnalyzer; -import org.jf.dexlib.Code.Analysis.RegisterType; -import org.jf.dexlib.Code.*; -import org.jf.dexlib.Util.AccessFlags; - -import java.io.IOException; -import java.util.BitSet; - //TODO: uncomment /*public class PreInstructionRegisterInfoMethodItem extends MethodItem { private final AnalyzedInstruction analyzedInstruction; diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/RegisterFormatter.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/RegisterFormatter.java index 28717b92..208ca004 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/RegisterFormatter.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/RegisterFormatter.java @@ -28,11 +28,8 @@ package org.jf.baksmali.Adaptors; -import com.google.common.base.Preconditions; -import org.jf.util.IndentingWriter; import org.jf.baksmali.baksmali; -import org.jf.dexlib.CodeItem; -import org.jf.dexlib.Util.AccessFlags; +import org.jf.util.IndentingWriter; import java.io.IOException; diff --git a/baksmali/src/main/java/org/jf/baksmali/baksmali.java b/baksmali/src/main/java/org/jf/baksmali/baksmali.java index f92a0c9d..28a11f00 100644 --- a/baksmali/src/main/java/org/jf/baksmali/baksmali.java +++ b/baksmali/src/main/java/org/jf/baksmali/baksmali.java @@ -30,7 +30,7 @@ package org.jf.baksmali; import com.google.common.collect.ImmutableList; import org.jf.baksmali.Adaptors.ClassDefinition; -import org.jf.dexlib.Code.Analysis.InlineMethodResolver; +import org.jf.dexlib2.analysis.InlineMethodResolver; import org.jf.dexlib2.iface.ClassDef; import org.jf.dexlib2.iface.DexFile; import org.jf.dexlib2.util.SyntheticAccessorResolver; diff --git a/util/src/main/java/org/jf/util/SparseIntArray.java b/util/src/main/java/org/jf/util/SparseIntArray.java new file mode 100644 index 00000000..2b8b5e0a --- /dev/null +++ b/util/src/main/java/org/jf/util/SparseIntArray.java @@ -0,0 +1,268 @@ +/* + * Copyright 2013, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.jf.util; + +/** + * SparseIntArrays map integers to integers. Unlike a normal array of integers, + * there can be gaps in the indices. It is intended to be more efficient + * than using a HashMap to map Integers to Integers. + */ +public class SparseIntArray { + /** + * Creates a new SparseIntArray containing no mappings. + */ + public SparseIntArray() { + this(10); + } + + /** + * Creates a new SparseIntArray containing no mappings that will not + * require any additional memory allocation to store the specified + * number of mappings. + */ + public SparseIntArray(int initialCapacity) { + mKeys = new int[initialCapacity]; + mValues = new int[initialCapacity]; + mSize = 0; + } + + /** + * Gets the int mapped from the specified key, or 0 + * if no such mapping has been made. + */ + public int get(int key) { + return get(key, 0); + } + + /** + * Gets the int mapped from the specified key, or the specified value + * if no such mapping has been made. + */ + public int get(int key, int valueIfKeyNotFound) { + int i = binarySearch(mKeys, 0, mSize, key); + + if (i < 0) { + return valueIfKeyNotFound; + } else { + return mValues[i]; + } + } + + /** + * Gets the int mapped from the specified key, or if not present, the + * closest key that is less than the specified key. + */ + public int getClosestSmaller(int key) { + int i = binarySearch(mKeys, 0, mSize, key); + + if (i < 0) { + i = ~i; + if (i > 0) { + i--; + } + return mValues[i]; + } else { + return mValues[i]; + } + } + + /** + * Removes the mapping from the specified key, if there was any. + */ + public void delete(int key) { + int i = binarySearch(mKeys, 0, mSize, key); + + if (i >= 0) { + removeAt(i); + } + } + + /** + * Removes the mapping at the given index. + */ + public void removeAt(int index) { + System.arraycopy(mKeys, index + 1, mKeys, index, mSize - (index + 1)); + System.arraycopy(mValues, index + 1, mValues, index, mSize - (index + 1)); + mSize--; + } + + /** + * Adds a mapping from the specified key to the specified value, + * replacing the previous mapping from the specified key if there + * was one. + */ + public void put(int key, int value) { + int i = binarySearch(mKeys, 0, mSize, key); + + if (i >= 0) { + mValues[i] = value; + } else { + i = ~i; + + if (mSize >= mKeys.length) { + int n = Math.max(mSize + 1, mKeys.length * 2); + + int[] nkeys = new int[n]; + int[] nvalues = new int[n]; + + // Log.e("SparseIntArray", "grow " + mKeys.length + " to " + n); + System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length); + System.arraycopy(mValues, 0, nvalues, 0, mValues.length); + + mKeys = nkeys; + mValues = nvalues; + } + + if (mSize - i != 0) { + // Log.e("SparseIntArray", "move " + (mSize - i)); + System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i); + System.arraycopy(mValues, i, mValues, i + 1, mSize - i); + } + + mKeys[i] = key; + mValues[i] = value; + mSize++; + } + } + + /** + * Returns the number of key-value mappings that this SparseIntArray + * currently stores. + */ + public int size() { + return mSize; + } + + /** + * Given an index in the range 0...size()-1, returns + * the key from the indexth key-value mapping that this + * SparseIntArray stores. + */ + public int keyAt(int index) { + return mKeys[index]; + } + + /** + * Given an index in the range 0...size()-1, returns + * the value from the indexth key-value mapping that this + * SparseIntArray stores. + */ + public int valueAt(int index) { + return mValues[index]; + } + + /** + * Returns the index for which {@link #keyAt} would return the + * specified key, or a negative number if the specified + * key is not mapped. + */ + public int indexOfKey(int key) { + return binarySearch(mKeys, 0, mSize, key); + } + + /** + * Returns an index for which {@link #valueAt} would return the + * specified key, or a negative number if no keys map to the + * specified value. + * Beware that this is a linear search, unlike lookups by key, + * and that multiple keys can map to the same value and this will + * find only one of them. + */ + public int indexOfValue(int value) { + for (int i = 0; i < mSize; i++) + if (mValues[i] == value) + return i; + + return -1; + } + + /** + * Removes all key-value mappings from this SparseIntArray. + */ + public void clear() { + mSize = 0; + } + + /** + * Puts a key/value pair into the array, optimizing for the case where + * the key is greater than all existing keys in the array. + */ + public void append(int key, int value) { + if (mSize != 0 && key <= mKeys[mSize - 1]) { + put(key, value); + return; + } + + int pos = mSize; + if (pos >= mKeys.length) { + int n = Math.max(pos + 1, mKeys.length * 2); + + int[] nkeys = new int[n]; + int[] nvalues = new int[n]; + + // Log.e("SparseIntArray", "grow " + mKeys.length + " to " + n); + System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length); + System.arraycopy(mValues, 0, nvalues, 0, mValues.length); + + mKeys = nkeys; + mValues = nvalues; + } + + mKeys[pos] = key; + mValues[pos] = value; + mSize = pos + 1; + } + + private static int binarySearch(int[] a, int start, int len, int key) { + int high = start + len, low = start - 1, guess; + + while (high - low > 1) { + guess = (high + low) / 2; + + if (a[guess] < key) + low = guess; + else + high = guess; + } + + if (high == start + len) + return ~(start + len); + else if (a[high] == key) + return high; + else + return ~high; + } + + private int[] mKeys; + private int[] mValues; + private int mSize; +}