@@ -32,6 +32,13 @@ import org.objectweb.asm.tree.MethodNode
3232import org.objectweb.asm.tree.TableSwitchInsnNode
3333import org.objectweb.asm.tree.VarInsnNode
3434
35+ private val TRACE_COMPARISON_METHODS =
36+ setOf (
37+ " traceCmpLongWrapper" ,
38+ " traceCmpDoubleWrapper" ,
39+ " traceCmpFloatWrapper" ,
40+ )
41+
3542internal class TraceDataFlowInstrumentor (
3643 private val types : Set <InstrumentationType >,
3744 private val callbackInternalClassName : String = " com/code_intelligence/jazzer/runtime/TraceDataFlowNativeCallbacks" ,
@@ -65,6 +72,18 @@ internal class TraceDataFlowInstrumentor(
6572 method.instructions.insertBefore(inst, longCmpInstrumentation())
6673 method.instructions.remove(inst)
6774 }
75+ Opcodes .DCMPG , Opcodes .DCMPL -> {
76+ if (InstrumentationType .CMP !in types) continue @loop
77+ val nanResult = if (inst.opcode == Opcodes .DCMPG ) 1 else - 1
78+ method.instructions.insertBefore(inst, doubleCmpInstrumentation(nanResult))
79+ method.instructions.remove(inst)
80+ }
81+ Opcodes .FCMPG , Opcodes .FCMPL -> {
82+ if (InstrumentationType .CMP !in types) continue @loop
83+ val nanResult = if (inst.opcode == Opcodes .FCMPG ) 1 else - 1
84+ method.instructions.insertBefore(inst, floatCmpInstrumentation(nanResult))
85+ method.instructions.remove(inst)
86+ }
6887 Opcodes .IF_ICMPEQ , Opcodes .IF_ICMPNE ,
6988 Opcodes .IF_ICMPLT , Opcodes .IF_ICMPLE ,
7089 Opcodes .IF_ICMPGT , Opcodes .IF_ICMPGE ,
@@ -78,15 +97,14 @@ internal class TraceDataFlowInstrumentor(
7897 -> {
7998 if (InstrumentationType .CMP !in types) continue @loop
8099 // The IF* opcodes are often used to branch based on the result of a compare
81- // instruction for a type other than int. The operands of this compare will
82- // already be reported via the instrumentation above (for non-floating point
83- // numbers) and the follow-up compare does not provide a good signal as all
84- // operands will be in {-1, 0, 1}. Skip instrumentation for it.
85- if (inst.previous?.opcode in listOf (Opcodes .DCMPG , Opcodes .DCMPL , Opcodes .FCMPG , Opcodes .DCMPL ) ||
86- (inst.previous as ? MethodInsnNode )?.name == " traceCmpLongWrapper"
87- ) {
100+ // instruction for a type other than int (long, float, double). The operands
101+ // of this compare will already be reported via the instrumentation above and
102+ // the follow-up compare does not provide a good signal as all operands will
103+ // be in {-1, 0, 1}. Skip instrumentation for it.
104+ if ((inst.previous as ? MethodInsnNode )?.name in TRACE_COMPARISON_METHODS ) {
88105 continue @loop
89106 }
107+
90108 method.instructions.insertBefore(inst, ifInstrumentation())
91109 }
92110 Opcodes .LOOKUPSWITCH , Opcodes .TABLESWITCH -> {
@@ -256,6 +274,20 @@ internal class TraceDataFlowInstrumentor(
256274 add(MethodInsnNode (Opcodes .INVOKESTATIC , callbackInternalClassName, " traceCmpLongWrapper" , " (JJI)I" , false ))
257275 }
258276
277+ private fun doubleCmpInstrumentation (nanResult : Int ) =
278+ InsnList ().apply {
279+ add(LdcInsnNode (nanResult))
280+ pushFakePc()
281+ add(MethodInsnNode (Opcodes .INVOKESTATIC , callbackInternalClassName, " traceCmpDoubleWrapper" , " (DDII)I" , false ))
282+ }
283+
284+ private fun floatCmpInstrumentation (nanResult : Int ) =
285+ InsnList ().apply {
286+ add(LdcInsnNode (nanResult))
287+ pushFakePc()
288+ add(MethodInsnNode (Opcodes .INVOKESTATIC , callbackInternalClassName, " traceCmpFloatWrapper" , " (FFII)I" , false ))
289+ }
290+
259291 private fun intCmpInstrumentation () =
260292 InsnList ().apply {
261293 add(InsnNode (Opcodes .DUP2 ))
0 commit comments