use of org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference in project android-bundle-support by lizhangqu.
the class PackageTreeCreator method addFields.
private void addFields(@NonNull DexClassNode classNode, @NonNull Iterable<? extends FieldReference> fieldRefs, Path dexFilePath) {
for (FieldReference fieldRef : fieldRefs) {
String fieldName = decodeFieldName(fieldRef, proguardMap);
String fieldType = decodeClassName(fieldRef.getType(), proguardMap);
String fieldSig = fieldType + " " + fieldName;
io.github.lizhangqu.intellij.android.bundle.analyzer.dex.tree.DexFieldNode fieldNode = classNode.getChildByType(fieldSig, io.github.lizhangqu.intellij.android.bundle.analyzer.dex.tree.DexFieldNode.class);
if (fieldNode == null) {
fieldNode = new io.github.lizhangqu.intellij.android.bundle.analyzer.dex.tree.DexFieldNode(fieldSig, ImmutableFieldReference.of(fieldRef));
classNode.add(fieldNode);
}
if (fieldRef instanceof DexBackedField) {
fieldNode.setDefined(true);
fieldNode.setUserObject(dexFilePath);
fieldNode.setSize(fieldNode.getSize() + ((DexBackedField) fieldRef).getSize());
} else if (fieldRef instanceof DexBackedFieldReference) {
fieldNode.setSize(fieldNode.getSize() + ((DexBackedFieldReference) fieldRef).getSize());
}
}
}
use of org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference in project android-bundle-support by lizhangqu.
the class PackageTreeCreator method getAllFieldReferencesByClassName.
@NonNull
private static Multimap<String, FieldReference> getAllFieldReferencesByClassName(@NonNull DexBackedDexFile dexFile) {
Multimap<String, FieldReference> fieldsByClass = ArrayListMultimap.create();
for (int i = 0, m = dexFile.getFieldCount(); i < m; i++) {
FieldReference fieldRef = new DexBackedFieldReference(dexFile, i);
fieldsByClass.put(fieldRef.getDefiningClass(), fieldRef);
}
return fieldsByClass;
}
use of org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference 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);
}
}
}
use of org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference in project smali by JesusFreke.
the class DexBackedField method getSize.
/**
* Calculate and return the private size of a field definition.
*
* Calculated as: field_idx_diff + access_flags + annotations overhead +
* initial value size + field reference size
*
* @return size in bytes
*/
public int getSize() {
int size = 0;
DexReader reader = dexFile.getBuffer().readerAt(startOffset);
// field_idx_diff
reader.readLargeUleb128();
// access_flags
reader.readSmallUleb128();
size += reader.getOffset() - startOffset;
Set<? extends DexBackedAnnotation> annotations = getAnnotations();
if (!annotations.isEmpty()) {
// 2 * uint overhead from field_annotation
size += 2 * 4;
}
if (initialValueOffset > 0) {
reader.setOffset(initialValueOffset);
if (initialValue != null) {
DexBackedEncodedValue.skipFrom(reader);
size += reader.getOffset() - initialValueOffset;
}
}
DexBackedFieldReference fieldRef = new DexBackedFieldReference(dexFile, fieldIndex);
size += fieldRef.getSize();
return size;
}
Aggregations