mirror of
https://github.com/revanced/smali.git
synced 2025-06-13 12:37:37 +02:00
When making a ClassDefItem from scratch, sort the static field initializers appropriately
git-svn-id: https://smali.googlecode.com/svn/trunk@404 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
@ -31,6 +31,9 @@ package org.jf.dexlib;
|
|||||||
import org.jf.dexlib.Util.Input;
|
import org.jf.dexlib.Util.Input;
|
||||||
import org.jf.dexlib.Util.AnnotatedOutput;
|
import org.jf.dexlib.Util.AnnotatedOutput;
|
||||||
import org.jf.dexlib.Util.AccessFlags;
|
import org.jf.dexlib.Util.AccessFlags;
|
||||||
|
import org.jf.dexlib.Util.TypeUtils;
|
||||||
|
import org.jf.dexlib.EncodedValue.EncodedValue;
|
||||||
|
import org.jf.dexlib.EncodedValue.ArrayEncodedSubValue;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@ -62,7 +65,11 @@ public class ClassDefItem extends Item<ClassDefItem> {
|
|||||||
* @param sourceFile The main source file that this class is defined in, or null if not available
|
* @param sourceFile The main source file that this class is defined in, or null if not available
|
||||||
* @param annotations The annotations for this class and its fields, methods and method parameters, or null if none
|
* @param annotations The annotations for this class and its fields, methods and method parameters, or null if none
|
||||||
* @param classData The <code>ClassDataItem</code> containing the method and field definitions for this class
|
* @param classData The <code>ClassDataItem</code> containing the method and field definitions for this class
|
||||||
* @param staticFieldInitializers The initial values for this class's static fields, or null if none
|
* @param staticFieldInitializers The initial values for this class's static fields, or null if none. The initial
|
||||||
|
* values should be in the same order as the static fields in the <code>ClassDataItem</code>. It can contain
|
||||||
|
* fewer items than static fields, in which case the remaining static fields will be initialized with a default
|
||||||
|
* value of null/0. The initial value for any fields that don't specifically have a value can be either the
|
||||||
|
* type-appropriate null/0 encoded value, or null.
|
||||||
*/
|
*/
|
||||||
private ClassDefItem(DexFile dexFile, TypeIdItem classType, int accessFlags, TypeIdItem superType,
|
private ClassDefItem(DexFile dexFile, TypeIdItem classType, int accessFlags, TypeIdItem superType,
|
||||||
TypeListItem implementedInterfaces, StringIdItem sourceFile,
|
TypeListItem implementedInterfaces, StringIdItem sourceFile,
|
||||||
@ -97,16 +104,28 @@ public class ClassDefItem extends Item<ClassDefItem> {
|
|||||||
* @param sourceFile The main source file that this class is defined in, or null if not available
|
* @param sourceFile The main source file that this class is defined in, or null if not available
|
||||||
* @param annotations The annotations for this class and its fields, methods and method parameters, or null if none
|
* @param annotations The annotations for this class and its fields, methods and method parameters, or null if none
|
||||||
* @param classData The <code>ClassDataItem</code> containing the method and field definitions for this class
|
* @param classData The <code>ClassDataItem</code> containing the method and field definitions for this class
|
||||||
* @param staticFieldInitializers The initial values for this class's static fields, or null if none
|
* @param staticFieldInitializers The initial values for this class's static fields, or null if none. The initial
|
||||||
|
* values should be in the same order as the fields in the <code>staticFields</code. parameter It can contain
|
||||||
|
* fewer items than static fields, in which case the remaining static fields will be initialized with a default
|
||||||
|
* value of null/0. The initial value for any fields that don't specifically have a value can be either the
|
||||||
|
* type-appropriate null/0 encoded value, or null.
|
||||||
|
* @param staticFields The static fields that correspond to the initial values in
|
||||||
|
* <code>staticFieldInitializers</code>. The static fields are needed in order to sort the initial values correctly
|
||||||
* @return a <code>ClassDefItem</code> for the given values, and that has been interned into the given
|
* @return a <code>ClassDefItem</code> for the given values, and that has been interned into the given
|
||||||
* <code>DexFile</code>
|
* <code>DexFile</code>
|
||||||
*/
|
*/
|
||||||
public static ClassDefItem getInternedClassDefItem(DexFile dexFile, TypeIdItem classType, int accessFlags,
|
public static ClassDefItem getInternedClassDefItem(DexFile dexFile, TypeIdItem classType, int accessFlags,
|
||||||
TypeIdItem superType, TypeListItem implementedInterfaces, StringIdItem sourceFile,
|
TypeIdItem superType, TypeListItem implementedInterfaces, StringIdItem sourceFile,
|
||||||
AnnotationDirectoryItem annotations, ClassDataItem classData,
|
AnnotationDirectoryItem annotations, ClassDataItem classData,
|
||||||
EncodedArrayItem staticFieldInitializers) {
|
EncodedValue[] staticFieldInitializers, ClassDataItem.EncodedField[] staticFields) {
|
||||||
|
EncodedArrayItem encodedArrayItem = null;
|
||||||
|
if(!dexFile.getInplace() && staticFieldInitializers != null) {
|
||||||
|
encodedArrayItem = makeStaticFieldInitializersItem(dexFile, staticFieldInitializers,
|
||||||
|
staticFields);
|
||||||
|
}
|
||||||
|
|
||||||
ClassDefItem classDefItem = new ClassDefItem(dexFile, classType, accessFlags, superType, implementedInterfaces,
|
ClassDefItem classDefItem = new ClassDefItem(dexFile, classType, accessFlags, superType, implementedInterfaces,
|
||||||
sourceFile, annotations, classData, staticFieldInitializers);
|
sourceFile, annotations, classData, encodedArrayItem);
|
||||||
return dexFile.ClassDefsSection.intern(classDefItem);
|
return dexFile.ClassDefsSection.intern(classDefItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,6 +305,81 @@ public class ClassDefItem extends Item<ClassDefItem> {
|
|||||||
unplacedClassDefsByType.remove(classDefItem.classType);
|
unplacedClassDefsByType.remove(classDefItem.classType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A helper method to sort the static field initializers and populate the default values as needed
|
||||||
|
* @param dexFile the <code>DexFile</code>
|
||||||
|
* @param staticFieldInitializers the initial values
|
||||||
|
* @param fields the fields that correspond to each initial value in <code>staticFieldInitializers</code>
|
||||||
|
* @return an interned EncodedArrayItem containing the static field initializers
|
||||||
|
*/
|
||||||
|
private static EncodedArrayItem makeStaticFieldInitializersItem(DexFile dexFile,
|
||||||
|
EncodedValue[] staticFieldInitializers,
|
||||||
|
ClassDataItem.EncodedField[] fields) {
|
||||||
|
class FieldAndValue {
|
||||||
|
public final EncodedValue value;
|
||||||
|
public final ClassDataItem.EncodedField field;
|
||||||
|
public FieldAndValue(ClassDataItem.EncodedField field, EncodedValue value) {
|
||||||
|
this.field = field;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (staticFieldInitializers == null || staticFieldInitializers.length == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int len = fields.length;
|
||||||
|
|
||||||
|
FieldAndValue[] fieldAndValues = new FieldAndValue[len];
|
||||||
|
|
||||||
|
for (int i=0; i<len; i++) {
|
||||||
|
EncodedValue encodedValue = null;
|
||||||
|
if (i < staticFieldInitializers.length) {
|
||||||
|
encodedValue = staticFieldInitializers[i];
|
||||||
|
}
|
||||||
|
ClassDataItem.EncodedField encodedField = fields[i];
|
||||||
|
|
||||||
|
fieldAndValues[i] = new FieldAndValue(encodedField, encodedValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
Arrays.sort(fieldAndValues, new Comparator<FieldAndValue>() {
|
||||||
|
public int compare(FieldAndValue a, FieldAndValue b) {
|
||||||
|
return a.field.compareTo(b.field);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
int lastIndex = -1;
|
||||||
|
for (int i=0; i<len; i++) {
|
||||||
|
FieldAndValue fav = fieldAndValues[i];
|
||||||
|
|
||||||
|
if (fav.value != null &&
|
||||||
|
(fav.value.compareTo(TypeUtils.makeDefaultValueForType(dexFile,
|
||||||
|
fav.field.field.getFieldType().getTypeDescriptor())) != 0)) {
|
||||||
|
lastIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//we don't have any non-null/non-default values, so we don't need to create an EncodedArrayItem
|
||||||
|
if (lastIndex == -1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
EncodedValue[] values = new EncodedValue[lastIndex+1];
|
||||||
|
|
||||||
|
for (int i=0; i<=lastIndex; i++) {
|
||||||
|
FieldAndValue fav = fieldAndValues[i];
|
||||||
|
EncodedValue encodedValue = fav.value;
|
||||||
|
if (encodedValue == null) {
|
||||||
|
encodedValue = TypeUtils.makeDefaultValueForType(dexFile,
|
||||||
|
fav.field.field.getFieldType().getTypeDescriptor());
|
||||||
|
}
|
||||||
|
|
||||||
|
values[i] = encodedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayEncodedSubValue encodedArrayValue = new ArrayEncodedSubValue(values);
|
||||||
|
return EncodedArrayItem.getInternedEncodedArrayItem(dexFile, encodedArrayValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
61
dexlib/src/main/java/org/jf/dexlib/Util/TypeUtils.java
Normal file
61
dexlib/src/main/java/org/jf/dexlib/Util/TypeUtils.java
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* [The "BSD licence"]
|
||||||
|
* Copyright (c) 2009 Ben Gruver
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.dexlib.Util;
|
||||||
|
|
||||||
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.EncodedValue.*;
|
||||||
|
|
||||||
|
public class TypeUtils
|
||||||
|
{
|
||||||
|
public static EncodedValue makeDefaultValueForType(DexFile dexFile, String type) {
|
||||||
|
EncodedValue subField;
|
||||||
|
switch (type.charAt(0)) {
|
||||||
|
case 'Z':
|
||||||
|
return BooleanEncodedValue.FalseValue;
|
||||||
|
case 'B':
|
||||||
|
return new ByteEncodedValue((byte)0);
|
||||||
|
case 'S':
|
||||||
|
return new ShortEncodedValue((short)0);
|
||||||
|
case 'C':
|
||||||
|
return new CharEncodedValue((char)0);
|
||||||
|
case 'I':
|
||||||
|
return new IntEncodedValue(0);
|
||||||
|
case 'J':
|
||||||
|
return new LongEncodedValue(0);
|
||||||
|
case 'F':
|
||||||
|
return new FloatEncodedValue(0);
|
||||||
|
case 'D':
|
||||||
|
return new DoubleEncodedValue(0);
|
||||||
|
case 'L':
|
||||||
|
case '[':
|
||||||
|
return NullEncodedValue.NullValue;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user