public JDynamicInvokeExpr( SootMethodRef bootstrapMethodRef, List<Value> bootstrapArgs, SootMethodRef methodRef, List<Value> methodArgs) { if (!methodRef.getSignature().startsWith("<" + SootClass.INVOKEDYNAMIC_DUMMY_CLASS_NAME + ": ")) throw new IllegalArgumentException( "Receiver type of JDynamicInvokeExpr must be " + SootClass.INVOKEDYNAMIC_DUMMY_CLASS_NAME + "!"); if (!bootstrapMethodRef.returnType().equals(RefType.v("java.lang.invoke.CallSite"))) { throw new IllegalArgumentException( "Return type of bootstrap method must be java.lang.invoke.CallSite!"); } this.bsmRef = bootstrapMethodRef; this.methodRef = methodRef; this.bsmArgBoxes = new ValueBox[bootstrapArgs.size()]; this.argBoxes = new ValueBox[methodArgs.size()]; for (int i = 0; i < bootstrapArgs.size(); i++) { // RoboVM note: Changed to handle InvokeExpr values in bootstrap args Value v = bootstrapArgs.get(i); if (v instanceof InvokeExpr) { this.bsmArgBoxes[i] = Jimple.v().newInvokeExprBox(v); } else { this.bsmArgBoxes[i] = Jimple.v().newImmediateBox(v); } } for (int i = 0; i < methodArgs.size(); i++) { this.argBoxes[i] = Jimple.v().newImmediateBox((Value) methodArgs.get(i)); } }
public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append(Jimple.DYNAMICINVOKE); buffer.append(" \""); buffer.append(methodRef.name()); // quoted method name (can be any UTF8 string) buffer.append("\" <"); buffer.append( SootMethod.getSubSignature( "" /* no method name here*/, methodRef.parameterTypes(), methodRef.returnType())); buffer.append(">("); for (int i = 0; i < argBoxes.length; i++) { if (i != 0) buffer.append(", "); buffer.append(argBoxes[i].getValue().toString()); } buffer.append(") "); buffer.append(bsmRef.getSignature()); buffer.append("("); for (int i = 0; i < bsmArgBoxes.length; i++) { if (i != 0) buffer.append(", "); buffer.append(bsmArgBoxes[i].getValue().toString()); } buffer.append(")"); return buffer.toString(); }
/** Dumps out the call chain in json format * */ public void dump_json(PrintStream fp, String indent) { fp.printf("%s{ %s,\n", indent, json_field("type", type)); fp.printf("%s %s,\n", indent, json_field("link", link)); String sig = method.getSignature(); fp.printf("%s %s,\n", indent, json_field("signature", sig)); if (stmt != null) { SootMethodRef invoke = stmt.getInvokeExpr().getMethodRef(); String invokeSig; try { SootMethod concrete = SootUtils.resolve(stmt.getInvokeExpr().getMethodRef()); invokeSig = concrete.getSignature(); } catch (CannotFindMethodException e1) { logger.debug("Cannot find concrete method for {} in SourceCallChainInfo.dump_json()", stmt); invokeSig = invoke.getSignature(); } if (!invokeSig.equals(sig)) { fp.printf("%s %s,\n", indent, json_field("source-signature", invokeSig)); } } SourceLocationTag slt = (stmt == null) ? SootUtils.getMethodLocation(method) : getSourceLocation(stmt); if (slt != null) { fp.printf("%s %s", indent, json_field("src-loc")); fp.printf( "{ %s, %s},\n", json_field("class", slt.getClz()), json_field("line", slt.getLine())); } fp.printf("%s %s,\n", indent, json_field("syscalls", syscalls)); fp.printf("%s %s,\n", indent, json_field("calls", calls)); if ((contents != null) && (contents.length > 0)) { fp.printf("%s %s,\n", indent, json_field("score", score)); fp.printf("%s %s [\n", indent, json_field("contents")); String delim = ""; for (SourceCallChainInfo cci : contents) { fp.print(delim); delim = ",\n"; cci.dump_json(fp, indent + " "); } fp.printf("\n%s]}", indent); } else { fp.printf("%s %s\n", indent, json_field("score", score)); fp.printf("%s}", indent); } }