Search in sources :

Example 1 with DexBackedTypeReference

use of org.jf.dexlib2.dexbacked.reference.DexBackedTypeReference in project android-bundle-support by lizhangqu.

the class DexReferences method gatherBackReferences.

/**
 * Goes through all the classes, methods, and fields, and gathers all possible references from
 * one type/method/field to another.
 *
 * @param files dex file
 */
private void gatherBackReferences(@NonNull DexBackedDexFile[] files) {
    Map<Reference, ImmutableReference> immutableReferencesBin = new HashMap<>();
    for (DexBackedDexFile file : files) {
        // build a map from class names (String) to actual TypeReferences,
        // as this information is not readily available to query through
        // the dexlib2 API.
        Map<String, ImmutableTypeReference> typesByName = new HashMap<>();
        for (int i = 0, m = file.getTypeCount(); i < m; i++) {
            ImmutableTypeReference immutableTypeRef = ImmutableTypeReference.of(new DexBackedTypeReference(file, i));
            typesByName.put(immutableTypeRef.getType(), immutableTypeRef);
        }
        // loop through all methods referenced in the dex file, mapping the following:
        for (int i = 0, m = file.getMethodCount(); i < m; i++) {
            MethodReference methodReference = new DexBackedMethodReference(file, i);
            // - return type => method
            ImmutableReference typeRef = typesByName.get(methodReference.getReturnType());
            addReference(typeRef, methodReference, immutableReferencesBin);
            // - all parameter types => method
            for (CharSequence parameterType : methodReference.getParameterTypes()) {
                typeRef = typesByName.get(parameterType.toString());
                addReference(typeRef, methodReference, immutableReferencesBin);
            }
        }
        // loop through all classes defined in the dex file, mapping the following:
        for (DexBackedClassDef classDef : file.getClasses()) {
            // - superclass => class
            ImmutableReference typeRef = typesByName.get(classDef.getSuperclass());
            addReference(typeRef, classDef, immutableReferencesBin);
            // - all implemented interfaces => class
            for (String iface : classDef.getInterfaces()) {
                typeRef = typesByName.get(iface);
                addReference(typeRef, classDef, immutableReferencesBin);
            }
            // map annotations => class
            for (Annotation annotation : classDef.getAnnotations()) {
                addAnnotation(immutableReferencesBin, typesByName, classDef, annotation);
            }
            // loop through all the methods defined in this class
            for (DexBackedMethod method : classDef.getMethods()) {
                // if the method has an implementation, loop through the bytecode
                // mapping any references that exist in dex instructions to the method.
                // Fortunately, dexlib2 marks every bytecode instruction that accepts
                // a reference with one or two interfaces: ReferenceInstruction
                // and DualReferenceInstruction.
                DexBackedMethodImplementation impl = method.getImplementation();
                if (impl != null) {
                    for (Instruction instruction : impl.getInstructions()) {
                        if (instruction instanceof ReferenceInstruction) {
                            Reference reference = ((ReferenceInstruction) instruction).getReference();
                            addReferenceAndEnclosingClass(immutableReferencesBin, typesByName, method, reference);
                        }
                        if (instruction instanceof DualReferenceInstruction) {
                            Reference reference = ((DualReferenceInstruction) instruction).getReference2();
                            addReferenceAndEnclosingClass(immutableReferencesBin, typesByName, method, reference);
                        }
                    }
                }
                // map annotations => method
                for (Annotation annotation : method.getAnnotations()) {
                    addAnnotation(immutableReferencesBin, typesByName, method, annotation);
                }
            }
            for (DexBackedField field : classDef.getFields()) {
                // map annotations => field
                for (Annotation annotation : field.getAnnotations()) {
                    addAnnotation(immutableReferencesBin, typesByName, field, annotation);
                }
            }
        }
        // a mapping from the field type => field
        for (int i = 0, m = file.getFieldCount(); i < m; i++) {
            FieldReference fieldRef = new DexBackedFieldReference(file, i);
            ImmutableReference typeRef = typesByName.get(fieldRef.getType());
            addReference(typeRef, fieldRef, immutableReferencesBin);
        }
    }
}
Also used : DexBackedTypeReference(org.jf.dexlib2.dexbacked.reference.DexBackedTypeReference) DexBackedFieldReference(org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference) FieldReference(org.jf.dexlib2.iface.reference.FieldReference) DexBackedFieldReference(org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference) MethodReference(org.jf.dexlib2.iface.reference.MethodReference) DexBackedMethodReference(org.jf.dexlib2.dexbacked.reference.DexBackedMethodReference) DexBackedTypeReference(org.jf.dexlib2.dexbacked.reference.DexBackedTypeReference) TypeReference(org.jf.dexlib2.iface.reference.TypeReference) Reference(org.jf.dexlib2.iface.reference.Reference) FieldReference(org.jf.dexlib2.iface.reference.FieldReference) DexBackedFieldReference(org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference) DualReferenceInstruction(org.jf.dexlib2.iface.instruction.DualReferenceInstruction) ReferenceInstruction(org.jf.dexlib2.iface.instruction.ReferenceInstruction) Instruction(org.jf.dexlib2.iface.instruction.Instruction) DualReferenceInstruction(org.jf.dexlib2.iface.instruction.DualReferenceInstruction) ReferenceInstruction(org.jf.dexlib2.iface.instruction.ReferenceInstruction) DualReferenceInstruction(org.jf.dexlib2.iface.instruction.DualReferenceInstruction) Annotation(org.jf.dexlib2.iface.Annotation) DexBackedMethodReference(org.jf.dexlib2.dexbacked.reference.DexBackedMethodReference) MethodReference(org.jf.dexlib2.iface.reference.MethodReference) DexBackedMethodReference(org.jf.dexlib2.dexbacked.reference.DexBackedMethodReference)

Example 2 with DexBackedTypeReference

use of org.jf.dexlib2.dexbacked.reference.DexBackedTypeReference in project android-bundle-support by lizhangqu.

the class PackageTreeCreator method getAllTypeReferencesByClassName.

@NonNull
private static Map<String, TypeReference> getAllTypeReferencesByClassName(@NonNull DexBackedDexFile dexFile) {
    HashMap<String, TypeReference> typesByName = new HashMap<>();
    for (int i = 0, m = dexFile.getTypeCount(); i < m; i++) {
        TypeReference typeRef = new DexBackedTypeReference(dexFile, i);
        typesByName.put(typeRef.getType(), typeRef);
    }
    return typesByName;
}
Also used : DexBackedTypeReference(org.jf.dexlib2.dexbacked.reference.DexBackedTypeReference) HashMap(java.util.HashMap) TypeReference(org.jf.dexlib2.iface.reference.TypeReference) DexBackedTypeReference(org.jf.dexlib2.dexbacked.reference.DexBackedTypeReference) NonNull(com.android.annotations.NonNull)

Aggregations

DexBackedTypeReference (org.jf.dexlib2.dexbacked.reference.DexBackedTypeReference)2 TypeReference (org.jf.dexlib2.iface.reference.TypeReference)2 NonNull (com.android.annotations.NonNull)1 HashMap (java.util.HashMap)1 DexBackedFieldReference (org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference)1 DexBackedMethodReference (org.jf.dexlib2.dexbacked.reference.DexBackedMethodReference)1 Annotation (org.jf.dexlib2.iface.Annotation)1 DualReferenceInstruction (org.jf.dexlib2.iface.instruction.DualReferenceInstruction)1 Instruction (org.jf.dexlib2.iface.instruction.Instruction)1 ReferenceInstruction (org.jf.dexlib2.iface.instruction.ReferenceInstruction)1 FieldReference (org.jf.dexlib2.iface.reference.FieldReference)1 MethodReference (org.jf.dexlib2.iface.reference.MethodReference)1 Reference (org.jf.dexlib2.iface.reference.Reference)1