Scenario P1:Class clz=Class.forName("string constant"); FORNAME(inUo)← SCALL(invo,mtd),MTDSTRING(mtd, "java.lang.Class:java.lang.Class forName(java.lang.String)"). RESOLVEDCLASSTYPE(inUo,type)← FoRNAME(invo),ACTUALARG(invo,1,arg), VARPOINTSTo(arg,const),STRINGToCLASS(const,type). CALLGRAPH(invo,clinit),VARPOINTSTo(clz,clzHeap)+ RESOLVEDCLASSTYPE(invo,type),TYPE-CLASSHEAP(type,clzHeap), MTDSTRING(clinit,type.toString()+".<clinit>()"),ACTUALRETURN(invo,clz). Scenario P2:Object obj clz.newInstance(); NEWINSTANCE(invo,clz)+ VCALL(invo,clz,mtd),MTDSTRINC(mtd,"java.lang.Class:java.lang.Object newInstance()"). CALLGRAPH(invo,init),HEAPTYPE(heap,type), VARPOINTSTo(this,heap),VARPOINTSTo(obj,heap) NEWINSTANCE(invo,clz).VARPOINTSTo(clz,clzHeap),TYPE-CLASSHEAP(type,clzHeap), NEwINSTANCEHEAP(type,heap),MTDSTRING(init,type.toString()+"<init>()"). THISVAR(init,this),ACTUALRETURN(invo,obj). Scenario P3:Field f =clz.getField("string constant"); GETFIELD(invo,clz) VCALL(invo,clz,mtd),MTDSTRING(mtd, "java.lang.Class:java.lang.reflect.Field getField(java.lang.String)"). RESOLVEDFIELD(invo,Ad) GeTFIELD(invo,clz),VARPOINTSTo(clz,clzHeap), TYPE-CLASSHEAP(type,clzHeap),ACTUALARC(invo,1,arg), VARPOINTSTo(arg,fldName),PUBLICFLD(type,fldName,fd). VARPOINTSTo(f,fdHeap) ReSOLVEDFIELD(invo,fld),FLD-FLDHEAP(fld,fdHeap),AcTUALRETURN(invo,f). Scenario P4:Object to f.get(obj); GEr(inpo,f)←- VCALL(invo,f,mtd),MTDSTRING(mtd, "java.lang.refect.Field:java.lang.Object get(java.lang.Object)"). VARPOINTSTo(to,valHeap) GET(invo,f),VARPOINTSTo(f,AdHeap),FLD-FLDHEAP(Ald,fdHeap), ACTUALARG(invo,1,obj),VARPOINTSTo(obj:baseHeap), FLDPOINTSTo(baseHeap,Ad,valHeap),ACTUALRETURN(invo,to). call is handled,identically as in Doop [4]but differently from 8],which approx- imates its target methods by disregarding the target object obj,on which the target methods are called. 4.3 Target Inference When a target method/field name or a target class type is unknown,ELF will in- fer the missing information,symbolized by red and blue circles along the dashed arrows in Figure 5.Below we give the Datalog rules for four representative sce- narios (out of a total of 73 scenarios mentioned earlier for target inference). Scenario I1:Class clz1 =CLass.forName(?);Aa =(A)clz2.newInstance(). The post-dominating cast (A)is used to infer the target class types of the objects reflectively created and pointed to by a,where clz2 points to a Class object of an unknown type that is initially pointed to by cll.Scenario P1: Class clz = Class.forName(“string constant”); ForName(invo) ← Scall(invo, mtd), MtdString(mtd, “java.lang.Class: java.lang.Class forName(java.lang.String)”). ResolvedClassType(invo, type) ← ForName(invo), ActualArg(invo, 1, arg), VarPointsTo(arg, const), StringToClass(const, type). CallGraph(invo, clinit), VarPointsTo(clz, clzHeap) ← ResolvedClassType(invo, type), Type-ClassHeap(type, clzHeap), MtdString(clinit, type.toString()+“.<clinit>()”), ActualReturn(invo, clz ). Scenario P2: Object obj = clz.newInstance(); NewInstance(invo, clz ) ← Vcall(invo, clz, mtd), MtdString(mtd, “java.lang.Class: java.lang.Object newInstance()”). CallGraph(invo, init), HeapType(heap, type), VarPointsTo(this, heap), VarPointsTo(obj, heap) ← NewInstance(invo, clz ), VarPointsTo(clz, clzHeap), Type-ClassHeap(type, clzHeap), NewInstanceHeap(type, heap), MtdString(init, type.toString()+“.<init>()”), ThisVar(init, this), ActualReturn(invo, obj ). Scenario P3: Field f = clz.getField(“string constant”); GetField(invo, clz ) ← Vcall(invo, clz, mtd), MtdString(mtd, “java.lang.Class: java.lang.reflect.Field getField(java.lang.String)”). ResolvedField(invo, fld) ← GetField(invo, clz ), VarPointsTo(clz, clzHeap), Type-ClassHeap(type, clzHeap), ActualArg(invo, 1, arg), VarPointsTo(arg, fldName), PublicFld(type, fldName, fld). VarPointsTo(f, fldHeap) ← ResolvedField(invo, fld), Fld-FldHeap(fld, fldHeap), ActualReturn(invo, f ). Scenario P4: Object to = f.get(obj); Get(invo, f ) ← Vcall(invo, f, mtd), MtdString(mtd, “java.lang.reflect.Field: java.lang.Object get(java.lang.Object)”). VarPointsTo(to, valHeap) ← Get(invo, f ), VarPointsTo(f, fldHeap), Fld-FldHeap(fld, fldHeap), ActualArg(invo, 1, obj ), VarPointsTo(obj, baseHeap), FldPointsTo(baseHeap, fld, valHeap), ActualReturn(invo, to). call is handled, identically as in Doop [4] but differently from [8], which approximates its target methods by disregarding the target object obj, on which the target methods are called. 4.3 Target Inference When a target method/field name or a target class type is unknown, Elf will infer the missing information, symbolized by red and blue circles along the dashed arrows in Figure 5. Below we give the Datalog rules for four representative scenarios (out of a total of 73 scenarios mentioned earlier for target inference). Scenario I1: Class clz1 = Class.forName(?); A a = (A) clz2.newInstance(). The post-dominating cast (A) is used to infer the target class types of the objects reflectively created and pointed to by a, where clz2 points to a Class object of an unknown type that is initially pointed to by clz1