1+ using System ;
12using System . Collections . Generic ;
23using System . Linq ;
34using dnlib . DotNet ;
@@ -12,15 +13,30 @@ internal sealed class Method
1213 {
1314 private readonly MemberRef sharedMem ;
1415 private readonly MemberRef prevLocation ;
16+ private readonly MemberRef onBranch ;
17+ private readonly bool enableOnBranchCallback ;
1518
19+ private readonly IMethod invoke ;
1620 private readonly CilBody body ;
1721 private readonly List < Instruction > instructions ;
1822 private readonly Dictionary < Instruction , Instruction > instrumented ;
1923
20- private Method ( MemberRef sharedMem , MemberRef prevLocation , MethodDef method )
24+ private Method (
25+ MemberRef sharedMem ,
26+ MemberRef prevLocation ,
27+ MemberRef onBranch ,
28+ bool enableOnBranchCallback ,
29+ MethodDef method )
2130 {
2231 this . sharedMem = sharedMem ;
2332 this . prevLocation = prevLocation ;
33+ this . onBranch = onBranch ;
34+ this . enableOnBranchCallback = enableOnBranchCallback ;
35+
36+ if ( enableOnBranchCallback )
37+ {
38+ invoke = method . Module . Import ( typeof ( Action < int , string > ) . GetMethod ( nameof ( Action . Invoke ) ) ) ;
39+ }
2440
2541 body = method . Body ;
2642 instructions = body . Instructions . ToList ( ) ;
@@ -30,16 +46,21 @@ private Method(MemberRef sharedMem, MemberRef prevLocation, MethodDef method)
3046 body . Instructions . Clear ( ) ;
3147
3248 FindInstrumentationTargets ( ) ;
33- Instrument ( ) ;
49+ Instrument ( method . FullName ) ;
3450 UpdateBranchTargets ( ) ;
3551 UpdateExceptionHandlers ( ) ;
3652
3753 body . OptimizeBranches ( ) ;
3854 }
3955
40- public static void Instrument ( MemberRef sharedMem , MemberRef prevLocation , MethodDef method )
56+ public static void Instrument (
57+ MemberRef sharedMem ,
58+ MemberRef prevLocation ,
59+ MemberRef onBranch ,
60+ bool enableOnBranchCallback ,
61+ MethodDef method )
4162 {
42- new Method ( sharedMem , prevLocation , method ) ;
63+ new Method ( sharedMem , prevLocation , onBranch , enableOnBranchCallback , method ) ;
4364 }
4465
4566 // Find all the locations that we want to instrument. These are:
@@ -83,13 +104,13 @@ private void FindInstrumentationTargets()
83104 // Regenerate the IL for the method. If some instruction was
84105 // previously marked as an instrumentation target, generate
85106 // the instrumentation code and put it before the instruction.
86- private void Instrument ( )
107+ private void Instrument ( string methodName )
87108 {
88109 foreach ( var ins in instructions )
89110 {
90111 if ( instrumented . ContainsKey ( ins ) )
91112 {
92- using ( var it = GenerateInstrumentationInstructions ( ) . GetEnumerator ( ) )
113+ using ( var it = GenerateInstrumentationInstructions ( methodName ) . GetEnumerator ( ) )
93114 {
94115 it . MoveNext ( ) ;
95116 instrumented [ ins ] = it . Current ;
@@ -111,7 +132,7 @@ private void Instrument()
111132 // var id = IdGenerator.Next();
112133 // SharpFuzz.Common.Trace.SharedMem[id ^ SharpFuzz.Common.Trace.PrevLocation]++;
113134 // SharpFuzz.Common.Trace.PrevLocation = id >> 1;
114- private IEnumerable < Instruction > GenerateInstrumentationInstructions ( )
135+ private IEnumerable < Instruction > GenerateInstrumentationInstructions ( string methodName )
115136 {
116137 int id = IdGenerator . Next ( ) ;
117138
@@ -128,6 +149,14 @@ private IEnumerable<Instruction> GenerateInstrumentationInstructions()
128149 yield return Instruction . Create ( OpCodes . Stind_I1 ) ;
129150 yield return Instruction . Create ( OpCodes . Ldc_I4 , id >> 1 ) ;
130151 yield return Instruction . Create ( OpCodes . Stsfld , prevLocation ) ;
152+
153+ if ( enableOnBranchCallback )
154+ {
155+ yield return Instruction . Create ( OpCodes . Ldsfld , onBranch ) ;
156+ yield return Instruction . Create ( OpCodes . Ldc_I4 , id ) ;
157+ yield return Instruction . Create ( OpCodes . Ldstr , methodName ) ;
158+ yield return Instruction . Create ( OpCodes . Callvirt , invoke ) ;
159+ }
131160 }
132161
133162 // Change all branch destinations to point to the first instruction
0 commit comments