public TempClassInfo(String dexFilePath, ClassDefItem classDefItem) { this.dexFilePath = dexFilePath; classType = classDefItem.getClassType().getTypeDescriptor(); isInterface = (classDefItem.getAccessFlags() & AccessFlags.INTERFACE.getValue()) != 0; TypeIdItem superclassType = classDefItem.getSuperclass(); if (superclassType == null) { this.superclassType = null; } else { this.superclassType = superclassType.getTypeDescriptor(); } interfaces = loadInterfaces(classDefItem); ClassDataItem classDataItem = classDefItem.getClassData(); if (classDataItem != null) { boolean[][] _staticMethods = new boolean[1][]; directMethods = loadDirectMethods(classDataItem, _staticMethods); staticMethods = _staticMethods[0]; virtualMethods = loadVirtualMethods(classDataItem); instanceFields = loadInstanceFields(classDataItem); } else { staticMethods = null; directMethods = null; virtualMethods = null; instanceFields = null; } }
assert classData != null; assert staticFieldInitializers.size() == classData.getStaticFields().length; encodedArrayItem = makeStaticFieldInitializersItem(dexFile, staticFieldInitializers); ClassDefItem classDefItem = new ClassDefItem(dexFile, classType, accessFlags, superType, implementedInterfaces, sourceFile, annotations, classData, encodedArrayItem); return dexFile.ClassDefsSection.intern(classDefItem);
public int placeSection(int offset) { currentOffset = offset; if (section.DexFile.getSortAllItems()) { //presort the list, to guarantee a unique ordering Collections.sort(section.items, new Comparator<ClassDefItem>() { public int compare(ClassDefItem a, ClassDefItem b) { return a.getClassType().compareTo(b.getClassType()); } }); } //we need to initialize the offset for all the classes to -1, so we can tell which ones //have been placed for (ClassDefItem classDefItem: section.items) { classDefItem.offset = -1; } for (ClassDefItem classDefItem: section.items) { placeClass(classDefItem); } for (ClassDefItem classDefItem: unplacedClassDefsByType.values()) { section.items.set(classDefItem.getIndex(), classDefItem); } return currentOffset; }
public int placeAt(int offset) { if (DexFile.this.getInplace()) { return super.placeAt(offset); } int ret = ClassDefItem.placeClassDefItems(this, offset); Collections.sort(this.items, new Comparator<ClassDefItem>() { public int compare(ClassDefItem a, ClassDefItem b) { return a.getOffset() - b.getOffset(); } }); this.offset = items.get(0).getOffset(); return ret; } };
private void placeClass(ClassDefItem classDefItem) { if (classDefItem.getOffset() == -1) { TypeIdItem superType = classDefItem.superType; ClassDefItem superClassDefItem = unplacedClassDefsByType.get(superType); if (superClassDefItem != null) { placeClass(superClassDefItem); } TypeListItem interfaces = classDefItem.implementedInterfaces; if (interfaces != null) { for (TypeIdItem interfaceType: interfaces.getTypes()) { ClassDefItem interfaceClass = unplacedClassDefsByType.get(interfaceType); if (interfaceClass != null) { placeClass(interfaceClass); } } } currentOffset = classDefItem.placeAt(currentOffset, currentIndex++); unplacedClassDefsByType.remove(classDefItem.classType); } } }
public int compare(ClassDefItem a, ClassDefItem b) { return a.getClassType().compareTo(b.getClassType()); } });
public UnresolvedClassInfo(String dexFilePath, ClassDefItem classDefItem) { this.dexFilePath = dexFilePath; classType = classDefItem.getClassType().getTypeDescriptor(); isInterface = (classDefItem.getAccessFlags() & AccessFlags.INTERFACE.getValue()) != 0; TypeIdItem superclassType = classDefItem.getSuperclass(); if (superclassType == null) { this.superclassType = null; } else { this.superclassType = superclassType.getTypeDescriptor(); } interfaces = loadInterfaces(classDefItem); ClassDataItem classDataItem = classDefItem.getClassData(); if (classDataItem != null) { boolean[][] _staticMethods = new boolean[1][]; directMethods = loadDirectMethods(classDataItem, _staticMethods); staticMethods = _staticMethods[0]; virtualMethods = loadVirtualMethods(classDataItem); instanceFields = loadInstanceFields(classDataItem); } else { staticMethods = null; directMethods = null; virtualMethods = null; instanceFields = null; } }
public int placeSection(int offset) { currentOffset = offset; if (section.DexFile.getSortAllItems()) { //presort the list, to guarantee a unique ordering Collections.sort(section.items, new Comparator<ClassDefItem>() { public int compare(ClassDefItem a, ClassDefItem b) { return a.getClassType().compareTo(b.getClassType()); } }); } //we need to initialize the offset for all the classes to -1, so we can tell which ones //have been placed for (ClassDefItem classDefItem: section.items) { classDefItem.offset = -1; } for (ClassDefItem classDefItem: section.items) { placeClass(classDefItem); } for (ClassDefItem classDefItem: unplacedClassDefsByType.values()) { section.items.set(classDefItem.getIndex(), classDefItem); } return currentOffset; }
private void placeClass(ClassDefItem classDefItem) { if (!classDefItem.isPlaced()) { TypeIdItem superType = classDefItem.superType; ClassDefItem superClassDefItem = unplacedClassDefsByType.get(superType); if (superClassDefItem != null) { placeClass(superClassDefItem); } TypeListItem interfaces = classDefItem.implementedInterfaces; if (interfaces != null) { for (TypeIdItem interfaceType: interfaces.getTypes()) { ClassDefItem interfaceClass = unplacedClassDefsByType.get(interfaceType); if (interfaceClass != null) { placeClass(interfaceClass); } } } currentOffset = classDefItem.placeAt(currentOffset, currentIndex++); unplacedClassDefsByType.remove(classDefItem.classType); } } }
/** {@inheritDoc} */ public int compareTo(ClassDefItem o) { //The actual sorting for this class is implemented in SortClassDefItemSection. //This method is just used for sorting the associated ClassDataItem items, so //we can just do the comparison based on the offsets of the items return this.getOffset() - o.getOffset(); }
private String[] loadInterfaces(ClassDefItem classDefItem) { TypeListItem typeList = classDefItem.getInterfaces(); if (typeList != null) { List<TypeIdItem> types = typeList.getTypes(); if (types != null && types.size() > 0) { String[] interfaces = new String[types.size()]; for (int i=0; i<interfaces.length; i++) { interfaces[i] = types.get(i).getTypeDescriptor(); } return interfaces; } } return null; }
return new MethodIdItem(dexFile); case TYPE_CLASS_DEF_ITEM: return new ClassDefItem(dexFile); case TYPE_TYPE_LIST: return new TypeListItem(dexFile);
ClassDataItem.EncodedMethod encodedMethod = classDefItem.getClassData().findDirectMethodByMethodId(methodIdItem); if (encodedMethod == null) { return null;
/** {@inheritDoc} */ public String getConciseIdentity() { if (parent == null) { return "class_data_item @0x" + Integer.toHexString(getOffset()); } return "class_data_item @0x" + Integer.toHexString(getOffset()) + " (" + parent.getClassType() +")"; }
public int placeAt(int offset) { if (DexFile.this.getInplace()) { return super.placeAt(offset); } int ret = ClassDefItem.placeClassDefItems(this, offset); Collections.sort(this.items); this.offset = items.get(0).getOffset(); return ret; }
/** {@inheritDoc} */ protected void writeItem(AnnotatedOutput out) { if (out.annotates()) { out.annotate(4, "class_type: " + classType.getTypeDescriptor()); out.annotate(4, "access_flags: " + AccessFlags.formatAccessFlagsForClass(accessFlags)); out.annotate(4, "superclass_type: " + (superType==null?"":superType.getTypeDescriptor())); out.annotate(4, "interfaces: " + (implementedInterfaces==null?"":implementedInterfaces.getTypeListString(" "))); out.annotate(4, "source_file: " + (sourceFile==null?"":sourceFile.getStringValue())); out.annotate(4, "annotations_off: " + (annotations==null?"":"0x"+Integer.toHexString(annotations.getOffset()))); out.annotate(4, "class_data_off:" + (classData==null?"":"0x"+Integer.toHexString(classData.getOffset()))); out.annotate(4, "static_values_off: " + (staticFieldInitializers==null?"":"0x"+Integer.toHexString(staticFieldInitializers.getOffset()))); } out.writeInt(classType.getIndex()); out.writeInt(accessFlags); out.writeInt(superType==null?-1:superType.getIndex()); out.writeInt(implementedInterfaces==null?0:implementedInterfaces.getOffset()); out.writeInt(sourceFile==null?-1:sourceFile.getIndex()); out.writeInt(annotations==null?0:annotations.getOffset()); out.writeInt(classData==null?0:classData.getOffset()); out.writeInt(staticFieldInitializers==null?0:staticFieldInitializers.getOffset()); }
private String[] loadInterfaces(ClassDefItem classDefItem) { TypeListItem typeList = classDefItem.getInterfaces(); if (typeList != null) { List<TypeIdItem> types = typeList.getTypes(); if (types != null && types.size() > 0) { String[] interfaces = new String[types.size()]; for (int i=0; i<interfaces.length; i++) { interfaces[i] = types.get(i).getTypeDescriptor(); } return interfaces; } } return null; }
return new MethodIdItem(dexFile); case TYPE_CLASS_DEF_ITEM: return new ClassDefItem(dexFile); case TYPE_TYPE_LIST: return new TypeListItem(dexFile);
ClassDataItem classDataItem = classDefItem.getClassData(); if (classDataItem == null) { return null;
/** {@inheritDoc} */ public String getConciseIdentity() { if (parent == null) { return "annotation_directory_item @0x" + Integer.toHexString(getOffset()); } return "annotation_directory_item @0x" + Integer.toHexString(getOffset()) + " (" + parent.getClassType() + ")"; }