@Override public boolean choose(XMethod method) { return accessFlagsAreConcrete(method.getAccessFlags()); } };
return findExactMethod(inv, cpg, methodChooser); return findInvocationLeastUpperBound(jClass, methodName, methodSig, methodChooser, opcode == Const.INVOKEINTERFACE);
public static @CheckForNull JavaClassAndMethod findInvocationLeastUpperBound(JavaClass jClass, String methodName, String methodSig, JavaClassAndMethodChooser methodChooser, boolean invokeInterface) throws ClassNotFoundException { JavaClassAndMethod result = findMethod(jClass, methodName, methodSig, methodChooser); if (result != null) { return result; } if (invokeInterface) { for (JavaClass i : jClass.getInterfaces()) { result = findInvocationLeastUpperBound(i, methodName, methodSig, methodChooser, invokeInterface); if (result != null) { return null; } } } else { JavaClass sClass = jClass.getSuperClass(); if (sClass != null) { return findInvocationLeastUpperBound(sClass, methodName, methodSig, methodChooser, invokeInterface); } } return null; }
JavaClassAndMethod targetMethod = findInvocationLeastUpperBound(invokeInstruction, cpg, CONCRETE_METHOD); if (targetMethod != null) { result.add(targetMethod); return resolveMethodCallTargets((ReferenceType) receiverType, invokeInstruction, cpg, receiverTypeIsExact);
private @CheckForNull XField lookupField(InstructionHandle handle, FieldInstruction fins) { XField field = instructionToFieldMap.get(handle); if (field == null) { field = Hierarchy.findXField(fins, getCPG()); instructionToFieldMap.put(handle, field); } return field; }
/** * Find a method in given list of classes, searching the classes in order. * * @param classList * list of classes in which to search * @param methodName * the name of the method * @param methodSig * the signature of the method * @param chooser * JavaClassAndMethodChooser to select which methods are * considered; it must return true for a method to be returned * @return the JavaClassAndMethod, or null if no such method exists in the * class */ public static JavaClassAndMethod findMethod(JavaClass[] classList, String methodName, String methodSig, JavaClassAndMethodChooser chooser) { JavaClassAndMethod m = null; for (JavaClass cls : classList) { if ((m = findMethod(cls, methodName, methodSig, chooser)) != null) { break; } } return m; }
if (opcode == Const.INVOKESTATIC) { INVOKESTATIC inv = (INVOKESTATIC) ins; if (Hierarchy.isInnerClassAccess(inv, cpg)) { InnerClassAccess access = Hierarchy.getInnerClassAccess(inv, cpg); XField field = Hierarchy.findXField((FieldInstruction) ins, cpg); if (field != null) { if (isLoad) {
ObjectType catchType = handler.getCatchType(); if (Hierarchy.isUniversalExceptionHandler(catchType)) { result.addAll(thrownExceptionSet); thrownExceptionSet.clear(); if (Hierarchy.isSubtype(thrownType, catchType)) { System.out.println("\tException is subtype of catch type: " + "will definitely catch"); } else if (Hierarchy.isSubtype(catchType, thrownType)) {
if (("forName".equals(methodName) && "java.lang.Class".equals(inv.getClassName(cpg)) || "class$".equals(methodName)) && "(Ljava/lang/String;)Ljava/lang/Class;".equals(inv.getSignature(cpg)) || (Hierarchy.isInnerClassAccess((INVOKESTATIC) inv, cpg) && loadedFieldSet.getField(handle) != null)) { return;
/** * Find XMethod for method in given list of classes, searching the classes * in order. * * @param classList * list of classes in which to search * @param methodName * the name of the method * @param methodSig * the signature of the method * @return the XMethod, or null if no such method exists in the class */ @Deprecated public static XMethod findXMethod(JavaClass[] classList, String methodName, String methodSig) { return findXMethod(classList, methodName, methodSig, ANY_METHOD); }
/** * Look up the method referenced by given InvokeInstruction. This method * does <em>not</em> look for implementations in super or subclasses * according to the virtual dispatch rules. * * @param inv * the InvokeInstruction * @param cpg * the ConstantPoolGen used by the class the InvokeInstruction * belongs to * @return the JavaClassAndMethod, or null if no such method is defined in * the class */ public static JavaClassAndMethod findExactMethod(InvokeInstruction inv, ConstantPoolGen cpg) throws ClassNotFoundException { return findExactMethod(inv, cpg, ANY_METHOD); }
private void handleLoad(FieldInstruction obj) { consumeStack(obj); Type type = obj.getType(getCPG()); if (!STRING_SIGNATURE.equals(type.getSignature())) { throw new IllegalArgumentException("type is not String: " + type); } try { String className = obj.getClassName(getCPG()); String fieldName = obj.getName(getCPG()); Field field = Hierarchy.findField(className, fieldName); if (field != null) { // If the field is final, we'll assume that the String value // is static. if (field.isFinal()) { pushValue(staticStringTypeInstance); } else { pushValue(type); } return; } } catch (ClassNotFoundException ex) { lookupFailureCallback.reportMissingClass(ex); } pushValue(type); } }
/** * <p>Find the least upper bound method in the class hierarchy which could be * called by the given InvokeInstruction. One reason this method is useful * is that it indicates which declared exceptions are thrown by the called * methods.</p> * <ul> * <li>For invokespecial, this is simply an exact lookup.</li> * <li>For invokestatic and invokevirtual, the named class is searched, * followed by superclasses up to the root of the object hierarchy * (java.lang.Object). Yes, invokestatic really is declared to check * superclasses. See VMSpec, 2nd ed, sec. 5.4.3.3.</li> * <li>For invokeinterface, the named class is searched, followed by all * interfaces transitively declared by the class. (Question: is the order * important here? Maybe the VM spec requires that the actual interface * desired is given, so the extended lookup will not be required. Should * check.)</li> * </ul> * * @param inv * the InvokeInstruction * @param cpg * the ConstantPoolGen used by the class the InvokeInstruction * belongs to * @return the JavaClassAndMethod, or null if no matching method can be * found */ public static @CheckForNull JavaClassAndMethod findInvocationLeastUpperBound(InvokeInstruction inv, ConstantPoolGen cpg) throws ClassNotFoundException { return findInvocationLeastUpperBound(inv, cpg, ANY_METHOD); }
@Override public void visitPUTSTATIC(PUTSTATIC obj) { if (doForwardSubstitution()) { XField xfield = Hierarchy.findXField(obj, getCPG()); if (xfield != null) { storeStaticField(xfield, obj, false); return; } } handleNormalInstruction(obj); }
/** * Find a method in given class. * * @param javaClass * the class * @param methodName * the name of the method * @param methodSig * the signature of the method * @return the JavaClassAndMethod, or null if no such method exists in the * class */ public static @CheckForNull JavaClassAndMethod findMethod(JavaClass javaClass, String methodName, String methodSig) { return findMethod(javaClass, methodName, methodSig, ANY_METHOD); }
if (opcode == Constants.INVOKESTATIC) { INVOKESTATIC inv = (INVOKESTATIC) ins; if (Hierarchy.isInnerClassAccess(inv, cpg)) { InnerClassAccess access = Hierarchy.getInnerClassAccess(inv, cpg); XField field = Hierarchy.findXField((FieldInstruction) ins, cpg); if (field != null) { if (isLoad) {
JavaClassAndMethod classAndMethod = findMethod(javaLangObject, methodName, methodSig, INSTANCE_METHOD); if (classAndMethod != null) { result.add(classAndMethod); JavaClassAndMethod upperBound = findMethod(receiverClass, methodName, methodSig, CONCRETE_METHOD); if (upperBound == null) { upperBound = findInvocationLeastUpperBound(receiverClass, methodName, methodSig, CONCRETE_METHOD, false); XMethod concreteSubtypeMethod = findMethod(subtype, methodName, methodSig, false); if (concreteSubtypeMethod != null && (concreteSubtypeMethod.getAccessFlags() & Const.ACC_ABSTRACT) == 0) { result.add(new JavaClassAndMethod(concreteSubtypeMethod));
private void analyzeMethod(ClassContext classContext, Method method) throws CFGBuilderException, ClassNotFoundException, DataflowAnalysisException { CFG cfg = classContext.getCFG(method); for (Iterator<Location> i = cfg.locationIterator(); i.hasNext();) { Location location = i.next(); Instruction ins = location.getHandle().getInstruction(); if (ins instanceof InvokeInstruction) { if (TARGET_METHOD != null && !((InvokeInstruction) ins).getMethodName(classContext.getConstantPoolGen()).equals(TARGET_METHOD)) { continue; } System.out.println("\n*******************************************************\n"); System.out.println("Method invocation: " + location.getHandle()); System.out.println("\tInvoking: " + SignatureConverter.convertMethodSignature((InvokeInstruction) ins, classContext.getConstantPoolGen())); JavaClassAndMethod proto = Hierarchy.findInvocationLeastUpperBound((InvokeInstruction) ins, classContext.getConstantPoolGen()); if (proto == null) { System.out.println("\tUnknown prototype method"); } else { System.out.println("\tPrototype method: class=" + proto.getJavaClass().getClassName() + ", method=" + proto.getMethod()); } Set<JavaClassAndMethod> calledMethodSet = Hierarchy.resolveMethodCallTargets((InvokeInstruction) ins, classContext.getTypeDataflow(method).getFactAtLocation(location), classContext.getConstantPoolGen()); System.out.println("\tTarget method set: " + calledMethodSet); } } }
throw new InvalidBytecodeException("stack underflow", methodGen, handle, e); } else if (Hierarchy.isInnerClassAccess(obj, cpg)) {