cecil icon indicating copy to clipboard operation
cecil copied to clipboard

ILProcessor.Replace bug with branch targets

Open JayWang0 opened this issue 10 years ago • 3 comments

image

this will cause some crital issues: IL0001 brtrue.s IL0002 IL0002 nop

Note: the IL0001's operand equals IL0002 but if we replace IL0002 to other instruction by use this method, it will cause the IL0001 link to wrong instruction.

I use a extension method as my workaround:


public static void ReplaceInstruction(this ILProcessor processor, Instruction from, Instruction to)
    {
        foreach (var item in processor.Body.Instructions)
        {
            var operInstruction = item.Operand as Instruction;
            if (operInstruction != null && operInstruction == from)
            {
                item.Operand = to;
            }
        }

        processor.Replace(from, to);
    }

JayWang0 avatar Sep 25 '14 08:09 JayWang0

I hit this too, I think it would be great it Cecil took care of this in ILProcessor.Replace.

lovettchris avatar Jun 10 '21 02:06 lovettchris

@lovettchris I noticed you took the ReplaceInstruction method from here in the linked PR, but it is incomplete, as switch operands and exception handlers also need to be modified.

See here for the method I use.

Also, note that you need to update references when removing instructions, but then maybe you intend to reinsert the removed instruction later on, so I'm not sure Cecil can safely do anything smart by itself 😕

ltrzesniewski avatar Jun 10 '21 07:06 ltrzesniewski

Thanks @ltrzesniewski, makes sense. Thanks for the exception handler code, I also have code that fixes up TryStart when I insert code before the existing TryStart and I want that to be the new start of the try/catch. So yeah, I can see that the semantics of all this can be tricky to generalize...

lovettchris avatar Jun 10 '21 17:06 lovettchris