Class CallResolver
- java.lang.Object
-
- proguard.analysis.CallResolver
-
- All Implemented Interfaces:
AttributeVisitor
,InstructionVisitor
,ClassVisitor
public class CallResolver extends java.lang.Object implements AttributeVisitor, ClassVisitor, InstructionVisitor
Collects all method invocations inside the analyzed methods.All method invocation instructions that appear in the bytecode are inspected, and their actual target method is calculated. Java has several invocation instructions, performing virtual, static, dynamic, interface and special calls. While most of these instructions have a constant operand specifying a method name, the actual method that will be called at runtime depends on multiple factors. Sometimes, e.g. when using virtual calls, the invocation target depends on the specific type of the first parameter on the stack, the so-called
this
pointer.This call analyzer performs a lookup process that adheres to the Java Virtual Machine specification. Being a static analysis, 100% precision cannot be guaranteed, as the specific type of variables at a specific program point is not always known in advance. But using the
PartialEvaluator
in combination with intraprocedural possible type analysis ofMultiTypedReferenceValue
objects, the resulting call graph should be a superset of the actual calls happening at runtime. This makes it a complete but potentially unsound analysis.In addition to resolving the call target, this analyzer also reconstructs the corresponding arguments and the return value. All of the collected information is wrapped in a
Call
object and passed to subscribedCallHandler
s.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
CallResolver.Builder
-
Constructor Summary
Constructors Constructor Description CallResolver(ClassPool programClassPool, ClassPool libraryClassPool, CallGraph callGraph, boolean clearCallValuesAfterVisit, boolean useDominatorAnalysis, boolean evaluateAllCode, boolean includeSubClasses, int maxPartialEvaluations, java.util.function.Supplier<java.lang.Boolean> shouldAnalyzeNextCodeAttribute, boolean skipIncompleteCalls, ValueFactory arrayValueFactory, boolean ignoreExceptions, ExecutingInvocationUnit.Builder executingInvocationUnitBuilder, boolean selectiveParameterReconstruction, java.util.Set<MethodSignature> interestingMethods, java.util.Set<java.util.function.Predicate<Call>> interestingCallPredicates, CallHandler... callHandlers)
Create a new call resolver.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description static java.lang.String
getDescriptor(java.lang.reflect.Method m)
Get the Descriptor of aMethod
.static MethodSignature
quickResolve(Instruction instruction, ProgramClass clazz)
Lightweight utility method to resolve the target of an invocation instruction on demand, without having to run a full scale analysis.void
visitAnyAttribute(Clazz clazz, Attribute attribute)
Visits any Attribute instance.void
visitAnyClass(Clazz clazz)
Visits any Clazz instance.void
visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction)
Visits any Instruction instance.void
visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
void
visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
void
visitProgramClass(ProgramClass programClass)
-
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
Methods inherited from interface proguard.classfile.attribute.visitor.AttributeVisitor
visitAnnotationDefaultAttribute, visitAnyAnnotationsAttribute, visitAnyParameterAnnotationsAttribute, visitAnyTypeAnnotationsAttribute, visitBootstrapMethodsAttribute, visitConstantValueAttribute, visitDeprecatedAttribute, visitDeprecatedAttribute, visitDeprecatedAttribute, visitDeprecatedAttribute, visitEnclosingMethodAttribute, visitExceptionsAttribute, visitInnerClassesAttribute, visitLineNumberTableAttribute, visitLocalVariableTableAttribute, visitLocalVariableTypeTableAttribute, visitMethodParametersAttribute, visitModuleAttribute, visitModuleMainClassAttribute, visitModulePackagesAttribute, visitNestHostAttribute, visitNestMembersAttribute, visitPermittedSubclassesAttribute, visitRecordAttribute, visitRuntimeInvisibleAnnotationsAttribute, visitRuntimeInvisibleAnnotationsAttribute, visitRuntimeInvisibleAnnotationsAttribute, visitRuntimeInvisibleAnnotationsAttribute, visitRuntimeInvisibleAnnotationsAttribute, visitRuntimeInvisibleParameterAnnotationsAttribute, visitRuntimeInvisibleTypeAnnotationsAttribute, visitRuntimeInvisibleTypeAnnotationsAttribute, visitRuntimeInvisibleTypeAnnotationsAttribute, visitRuntimeInvisibleTypeAnnotationsAttribute, visitRuntimeInvisibleTypeAnnotationsAttribute, visitRuntimeInvisibleTypeAnnotationsAttribute, visitRuntimeVisibleAnnotationsAttribute, visitRuntimeVisibleAnnotationsAttribute, visitRuntimeVisibleAnnotationsAttribute, visitRuntimeVisibleAnnotationsAttribute, visitRuntimeVisibleAnnotationsAttribute, visitRuntimeVisibleParameterAnnotationsAttribute, visitRuntimeVisibleTypeAnnotationsAttribute, visitRuntimeVisibleTypeAnnotationsAttribute, visitRuntimeVisibleTypeAnnotationsAttribute, visitRuntimeVisibleTypeAnnotationsAttribute, visitRuntimeVisibleTypeAnnotationsAttribute, visitRuntimeVisibleTypeAnnotationsAttribute, visitSignatureAttribute, visitSignatureAttribute, visitSignatureAttribute, visitSignatureAttribute, visitSignatureAttribute, visitSourceDebugExtensionAttribute, visitSourceDirAttribute, visitSourceFileAttribute, visitStackMapAttribute, visitStackMapTableAttribute, visitSyntheticAttribute, visitSyntheticAttribute, visitSyntheticAttribute, visitSyntheticAttribute, visitUnknownAttribute
-
Methods inherited from interface proguard.classfile.visitor.ClassVisitor
visitLibraryClass
-
Methods inherited from interface proguard.classfile.instruction.visitor.InstructionVisitor
visitAnySwitchInstruction, visitBranchInstruction, visitLookUpSwitchInstruction, visitSimpleInstruction, visitTableSwitchInstruction, visitVariableInstruction
-
-
-
-
Constructor Detail
-
CallResolver
public CallResolver(ClassPool programClassPool, ClassPool libraryClassPool, CallGraph callGraph, boolean clearCallValuesAfterVisit, boolean useDominatorAnalysis, boolean evaluateAllCode, boolean includeSubClasses, int maxPartialEvaluations, java.util.function.Supplier<java.lang.Boolean> shouldAnalyzeNextCodeAttribute, boolean skipIncompleteCalls, ValueFactory arrayValueFactory, boolean ignoreExceptions, ExecutingInvocationUnit.Builder executingInvocationUnitBuilder, boolean selectiveParameterReconstruction, java.util.Set<MethodSignature> interestingMethods, java.util.Set<java.util.function.Predicate<Call>> interestingCallPredicates, CallHandler... callHandlers)
Create a new call resolver.- Parameters:
programClassPool
-ClassPool
containing the classes whose calls should be analyzed.libraryClassPool
- AuxiliaryClassPool
containing framework classes. Their calls are not resolved, but the class structure information (i.e. contained methods) is needed when resolving calls whose target lies in such a library class.callGraph
- TheCallGraph
to fill with all discoveredCall
s.clearCallValuesAfterVisit
- If true,Call.clearValues()
will be called afterCallHandler.handleCall(Call, TracedStack, TracedVariables)
. This makes it possible to analyze arguments and the return value of calls while still adding them to aCallGraph
afterwards, as call graph analysis itself usually only requires the call locations and their targets, not the arguments or return value.useDominatorAnalysis
- If true, a dominator analysis is carried out using theDominatorCalculator
for each method, in order to be able to fill theCall.controlFlowDependent
flag.evaluateAllCode
- SeePartialEvaluator.Builder.setEvaluateAllCode(boolean)
.includeSubClasses
- If true, virtual calls on class fields, parameters and return values of other methods will take all possible subclasses into account. This is necessary for a more complete call graph, because the runtime type of these objects is not controlled by the current method. E.g. a method that declares its return type to be of type A might also return an object of type B in case B extends A. The same is true for class fields and parameters, so in order to really find all potential calls, this circumstance needs to be modeled. For objects of declared typeObject
this will be skipped, as the fact that every single Java class is a subclass of object would lead to an immense blow-up of the call graph.maxPartialEvaluations
- SeePartialEvaluator.Builder.stopAnalysisAfterNEvaluations(int)
.shouldAnalyzeNextCodeAttribute
- If returns true, the next code attribute will be analyzed. Otherwise, the code attribute will be skipped.skipIncompleteCalls
- If true, any discovered call that would return true forCall.hasIncompleteTarget()
will be discarded and not be forwarded toCallHandler.handleCall(Call, TracedStack, TracedVariables)
.callHandlers
-CallHandler
s that are interested in the results of this analysis.
-
-
Method Detail
-
quickResolve
public static MethodSignature quickResolve(Instruction instruction, ProgramClass clazz)
Lightweight utility method to resolve the target of an invocation instruction on demand, without having to run a full scale analysis. This means the following for the different invocation types:- invokestatic: Full target resolution possible.
- invokevirtual, invokespecial, invokeinterface: Method name and descriptor.
- invokedynamic: Only descriptor.
- Parameters:
instruction
- The invocation instruction to analyze.clazz
- TheProgramClass
containing this instruction.- Returns:
- A
MethodSignature
containing as much information about the invocation target as we can confidently know without needing more in-depth analysis.
-
visitAnyClass
public void visitAnyClass(Clazz clazz)
Description copied from interface:ClassVisitor
Visits any Clazz instance. The more specific default implementations of this interface delegate to this method.- Specified by:
visitAnyClass
in interfaceClassVisitor
-
visitProgramClass
public void visitProgramClass(ProgramClass programClass)
- Specified by:
visitProgramClass
in interfaceClassVisitor
-
visitAnyAttribute
public void visitAnyAttribute(Clazz clazz, Attribute attribute)
Description copied from interface:AttributeVisitor
Visits any Attribute instance. The more specific default implementations of this interface delegate to this method.- Specified by:
visitAnyAttribute
in interfaceAttributeVisitor
-
visitCodeAttribute
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
- Specified by:
visitCodeAttribute
in interfaceAttributeVisitor
-
visitAnyInstruction
public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction)
Description copied from interface:InstructionVisitor
Visits any Instruction instance. The more specific default implementations of this interface delegate to this method.- Specified by:
visitAnyInstruction
in interfaceInstructionVisitor
-
visitConstantInstruction
public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
- Specified by:
visitConstantInstruction
in interfaceInstructionVisitor
-
getDescriptor
public static java.lang.String getDescriptor(java.lang.reflect.Method m)
Get the Descriptor of aMethod
.
-
-