public class CallResolver extends java.lang.Object implements AttributeVisitor, ClassVisitor, InstructionVisitor
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 of
MultiTypedReferenceValue 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 subscribed CallVisitors.
| Modifier and Type | Class and Description |
|---|---|
static class |
CallResolver.Builder |
| Constructor and 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,
CallVisitor... visitors)
Create a new call resolver.
|
| Modifier and Type | Method and Description |
|---|---|
static java.lang.String |
getDescriptor(java.lang.reflect.Method m)
Get the Descriptor of a
Method. |
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) |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitvisitAnnotationDefaultAttribute, 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, visitUnknownAttributevisitLibraryClassvisitAnySwitchInstruction, visitBranchInstruction, visitLookUpSwitchInstruction, visitSimpleInstruction, visitTableSwitchInstruction, visitVariableInstructionpublic 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, CallVisitor... visitors)
programClassPool - ClassPool containing the classes whose
calls should be analyzed.libraryClassPool - Auxiliary ClassPool 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 - The CallGraph to fill with all discovered Calls.clearCallValuesAfterVisit - If true, Call.clearValues() will be called after
CallVisitor.visitCall(Call). This makes it possible
to analyze arguments and the return value of calls while still
adding them to a CallGraph 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 the DominatorCalculator for each
method, in order to be able to fill the
Call.controlFlowDependent flag.evaluateAllCode - See PartialEvaluator.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
type Object 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 - See PartialEvaluator.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 for
Call.hasIncompleteTarget() will be discarded and not be
forwarded to CallVisitor.visitCall(Call).visitors - CallVisitors that are interested in the
results of this analysis.public static MethodSignature quickResolve(Instruction instruction, ProgramClass clazz)
instruction - The invocation instruction to analyze.clazz - The ProgramClass containing this instruction.MethodSignature containing as much information about the invocation target
as we can confidently know without needing more in-depth analysis.public void visitAnyClass(Clazz clazz)
ClassVisitorvisitAnyClass in interface ClassVisitorpublic void visitProgramClass(ProgramClass programClass)
visitProgramClass in interface ClassVisitorpublic void visitAnyAttribute(Clazz clazz, Attribute attribute)
AttributeVisitorvisitAnyAttribute in interface AttributeVisitorpublic void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
visitCodeAttribute in interface AttributeVisitorpublic void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction)
InstructionVisitorvisitAnyInstruction in interface InstructionVisitorpublic void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
visitConstantInstruction in interface InstructionVisitorpublic static java.lang.String getDescriptor(java.lang.reflect.Method m)
Method.