<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=us-ascii"><meta name=Generator content="Microsoft Word 15 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:Wingdings;
        panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:#0563C1;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:#954F72;
        text-decoration:underline;}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
        {mso-style-priority:34;
        margin-top:0cm;
        margin-right:0cm;
        margin-bottom:0cm;
        margin-left:36.0pt;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
span.E-MailFormatvorlage17
        {mso-style-type:personal-compose;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:70.85pt 70.85pt 2.0cm 70.85pt;}
div.WordSection1
        {page:WordSection1;}
/* List Definitions */
@list l0
        {mso-list-id:1717967782;
        mso-list-type:hybrid;
        mso-list-template-ids:1329638572 1648249804 67567619 67567621 67567617 67567619 67567621 67567617 67567619 67567621;}
@list l0:level1
        {mso-level-start-at:3;
        mso-level-number-format:bullet;
        mso-level-text:-;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:"Calibri",sans-serif;
        mso-fareast-font-family:Calibri;
        mso-bidi-font-family:"Times New Roman";}
@list l0:level2
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:"Courier New";}
@list l0:level3
        {mso-level-number-format:bullet;
        mso-level-text:\F0A7;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Wingdings;}
@list l0:level4
        {mso-level-number-format:bullet;
        mso-level-text:\F0B7;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Symbol;}
@list l0:level5
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:"Courier New";}
@list l0:level6
        {mso-level-number-format:bullet;
        mso-level-text:\F0A7;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Wingdings;}
@list l0:level7
        {mso-level-number-format:bullet;
        mso-level-text:\F0B7;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Symbol;}
@list l0:level8
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:"Courier New";}
@list l0:level9
        {mso-level-number-format:bullet;
        mso-level-text:\F0A7;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Wingdings;}
ol
        {margin-bottom:0cm;}
ul
        {margin-bottom:0cm;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body lang=DE link="#0563C1" vlink="#954F72"><div class=WordSection1><p class=MsoNormal><span lang=EN-GB>Hello,<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-GB>We want to extend the soot framework such that callgraph construction considers lambda expressions.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB>Since lambda expressions are compiled to invokedynamic instructions and these aren't handled in the framework yet we made the following changes:<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-GB>1. Initially, in soot.asm.AsmMethodSource convertInvokeDynamicInsn() there was a SootMethodRef created to a dummy class like that:<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-GB>SootClass bclass = Scene.v().getSootClass(SootClass.INVOKEDYNAMIC_DUMMY_CLASS_NAME);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB>[...]<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB>SootMethodRef methodRef = Scene.v().makeMethodRef(bclass, insn.name, parameterTypes, returnType, true); <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB>DynamicInvokeExpr indy = Jimple.v().newDynamicInvokeExpr(bsmMethodRef, bsmMethodArgs, methodRef, methodArgs);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-GB>We replaced that by:<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-GB>SootMethodRef methodRef = LambdaProxyBuilder.v().generateProxy(insn,toSootMethodRef((Handle)insn.bsmArgs[1])); <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB>DynamicInvokeExpr indy = Jimple.v().newDynamicInvokeExpr(bsmMethodRef, bsmMethodArgs, methodRef, methodArgs);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-GB>LambdaProxyBuilder is a class written by us which creates a jimple class file implementing the required interface from the lambda expression.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB>The generated class from LambdaProxyBuilder provides a static factory method newInstance(), so the idea is to let the dynamicinvoke point to the newInstance() method of our generated class such that the variable on the left side of the dynamicinvoke holds an object of that new type.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-GB>2. In soot.jimple.toolkits.callgraph.OnFlyCallGraphBuilder findReceivers() is an empty if branch for dynamicinvoke expressions. As mentioned before, we reduce the invokedynamic to a regular static invoke pointing towards the factory method of our generated class so we try to apply the same logic as it is used for static invokes:<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-GB>else if (ie instanceof DynamicInvokeExpr) { <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB> SootMethod tgt = ie.getMethod();<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB> if(tgt!=null) {<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB> addEdge(m, s, tgt);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB>} <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-GB>3. In soot.Kind we added dynamic edges to the method isExplicit() like so:<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-GB>/** Returns true if the call is due to an explicit invoke statement. */<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB>public boolean isExplicit() {<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB> return isInstance() || isStatic() || isDynamic();<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB>}<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-GB>With those extensions we get good results for CHA and we also get the required edges for very simple cases using SPARK. However, when the variable on the left side of the dynamicinvoke is passed to another method, the propagation of the type doesn't seem to work because the points-to set of the parameter is empty. For example if we have the jimple code:<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-GB>[...]<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB>com.lambda.interprocedural.DataFlowTarget2_lambda$0Proxy $r5;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB>[...]<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB>$r5 = dynamicinvoke "newInstance" <com.lambda.interprocedural.DataFlowTarget2_lambda$0Proxy (java.lang.String,java.util.concurrent.atomic.LongAdder,java.util.concurrent.atomic.LongAdder)>(r8, r1, r9) <java.lang.invoke.LambdaMetafactory: java.lang.invoke.CallSite metafactory(java.lang.invoke.MethodHandles$Lookup,java.lang.String,java.lang.invoke.MethodType,java.lang.invoke.MethodType,java.lang.invoke.MethodHandle,java.lang.invoke.MethodType)>(class "(Ljava/io/File;)Z", handle: <com.lambda.interprocedural.DataFlowTarget2: boolean lambda$0(java.lang.String,java.util.concurrent.atomic.LongAdder,java.util.concurrent.atomic.LongAdder,java.io.File)>, class "(Ljava/io/File;)Z");<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB>virtualinvoke r0.<java.io.File: java.io.File[] listFiles(java.io.FileFilter)>($r5);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-GB>the points-to set of $r5 holds our generated type. When $r5 is passed to the method listFiles(), the corresponding parameter's points-to set is empty and thus we don't get the desired edges in the cg.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-GB>Any help would be appreciated.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-GB><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-GB>- Michael<o:p></o:p></span></p></div></body></html>