Ok, thanks for the answer.
Here is a quick extension method I wrote that updates the exception
handlers:
public static void SafeRemove(this Mono.Cecil.Cil.ILProcessor
p, Mono.Cecil.Cil.Instruction i)
{
foreach (var eh in p.Body.ExceptionHandlers)
{
if (eh.TryStart == i)
eh.TryStart = i.Next;
if (eh.TryEnd.Previous == i)
eh.TryEnd = i.Previous;
if (eh.HandlerStart == i)
eh.HandlerStart = i.Next;
if (eh.HandlerEnd.Previous == i)
eh.HandlerEnd = i.Previous;
if (eh.FilterStart == i)
eh.FilterStart = i.Next;
}
p.Remove(i);
}
On 8 Jul., 12:57, Alex <[email protected]> wrote:
> Hi Kenneth,
>
> As far as I know, you have to adjust exception handlers manually.
> Since Cecil uses references to refer to instructions (as opposed to
> offsets), it won't pick anything up if you completely remove an
> instruction. Also, internally, Cecil only sets properties on
> ExceptionHandler when reading modules.
>
> Regards,
> Alex
>
>
>
>
>
>
>
> On Fri, Jul 8, 2011 at 11:46 AM, Kenneth Skovhede <[email protected]> wrote:
> > I have some function that I load with Mono.Cecil, modify and write
> > back.
> > This generally works fine, but if I remove the nop operations, the Try/
> > Catch handlers
> > break (the TryBegin target instruction is the nop instruction being
> > removed).
>
> > What appears to happen is that even though I use the ILProcessor to
> > remove the
> > instruction, the ExceptionHandler still has a reference to the removed
> > instruction.
>
> > For some reason this works fine for the first execption handler, which
> > gets the
> > TryBegin offset 0x0b, but the second exception handler should get
> > 0x2a, but also
> > gets 0x0b. (In Cecil 0.6.7 it got 0x00).
>
> > If google groups mess up the formating, I have also put the code on
> > pastebin:
> >http://pastebin.com/HDScfLMw
>
> > My question is, is there some easy fixup method/trick to get this
> > working?
> > Or do I need to create a fixup function that I execute prior to
> > instruction removal
> > that updates the exception handlers?
>
> > Regards, Kenneth
>
> > [NORMAL]
> > .method public hidebysig virtual instance float32 Op(float32 a,
> > float32 b) cil managed
> > {
> > // Code size 65 (0x41)
> > .maxstack 2
> > .locals init (float32 V_0,
> > float32 V_1,
> > float32 V_2)
> > IL_0000: ldc.i4 0x579223a3
> > IL_0005: ldc.i4.0
> > IL_0006: call void EnterMethod(int32, int32)
> > .try
> > {
> > IL_000b: nop
> > IL_000c: ldarg.0
> > IL_000d: ldarg.1
> > IL_000e: sub
> > IL_000f: stloc.0
> > IL_0010: leave.s IL_0018
> > } // end .try
> > fault
> > {
> > IL_0012: call void LeaveMethod()
> > IL_0017: endfinally
> > } // end handler
> > IL_0018: call void LeaveMethod()
> > IL_001d: ldloc.0
> > IL_001e: stloc.1
> > IL_001f: ldc.i4 0x579223a3
> > IL_0024: ldc.i4.1
> > IL_0025: call void EnterMethod(int32, int32)
> > .try
> > {
> > IL_002a: nop
> > IL_002b: ldloc.1
> > IL_002c: call float32 [mscorlib]System.Math::Abs(float32)
> > IL_0031: stloc.2
> > IL_0032: leave.s IL_003a
> > } // end .try
> > fault
> > {
> > IL_0034: call void LeaveMethod()
> > IL_0039: endfinally
> > } // end handler
> > IL_003a: call void LeaveMethod()
> > IL_003f: ldloc.2
> > IL_0040: ret
> > }
>
> > [MODIFIED]
> > .method public hidebysig virtual instance float32 Op(float32 a,
> > float32 b) cil managed
> > {
> > // Code size 63 (0x3f)
> > .maxstack 2
> > .locals init (float32 V_0,
> > float32 V_1,
> > float32 V_2)
> > IL_0000: ldc.i4 0x579223a3
> > IL_0005: ldc.i4.0
> > IL_0006: call void EnterMethod(int32, int32)
> > .try
> > {
> > .try
> > {
> > IL_000b: ldarg.0
> > IL_000c: ldarg.1
> > IL_000d: sub
> > IL_000e: stloc.0
> > IL_000f: leave.s IL_0017
> > } // end .try
> > fault
> > {
> > IL_0011: call void LeaveMethod()
> > IL_0016: endfinally
> > } // end handler
> > IL_0017: call void LeaveMethod()
> > IL_001c: ldloc.0
> > IL_001d: stloc.1
> > IL_001e: ldc.i4 0x579223a3
> > IL_0023: ldc.i4.1
> > IL_0024: call void EnterMethod(int32, int32)
> > IL_0029: ldloc.1
> > IL_002a: call float32 [mscorlib]System.Math::Abs(float32)
> > IL_002f: stloc.2
> > IL_0030: leave.s IL_0038
> > } // end .try
> > fault
> > {
> > IL_0032: call void LeaveMethod()
> > IL_0037: endfinally
> > } // end handler
> > IL_0038: call void LeaveMethod()
> > IL_003d: ldloc.2
> > IL_003e: ret
> > }
>
> > --
> > --
> > mono-cecil
--
--
mono-cecil