Reading the type the second argument passed to String.Format(string s, object obj) method using Mono.cecil

72 views
Skip to first unread message

rumpa.maji

unread,
Jul 5, 2011, 5:43:58 AM7/5/11
to mono-...@googlegroups.com
Hello All,

I am facing a problem while using Mono.Cecil.
I have the below code in my program,
private void CurrentDomainUnhandledException(object sender,
UnhandledExceptionEventArgs args)
{
String.Format("Unhandled AppDomain exception", args);
}
I am facing a problem in reading the type of args using Mono.Cecil
It is giving me information about "Unhandled AppDomain exception" argument
and its type as string and the Operand is also not null, but for the second
argument "args", it is showing it as ldloc or ldarg.2 and
instruction.Operand is showing as null. I want to retrieve the Operand for
"args".

My requirement is , i want to read the type of the "args" argument, in this
example, it is "UnhandledExceptionEventArgs".

Please help me.
Thanx in Advance.

Regards
Rumpa Maji

--
View this message in context: http://mono.1490590.n4.nabble.com/Reading-the-type-the-second-argument-passed-to-String-Format-string-s-object-obj-method-using-Mono-cl-tp3645549p3645549.html
Sent from the Mono - Cecil mailing list archive at Nabble.com.

Gábor Kozár

unread,
Jul 5, 2011, 9:53:06 AM7/5/11
to mono-...@googlegroups.com
Hi,

First of all, this line won't work:

String.Format("Unhandled AppDomain exception", args);

You need to have {0} somewhere in your string, which will be replaced by args.ToString(). That's what String.Format() does. I'm not sure that this will cause a runtime exception, or will just have your extra parameter ignored, but still figured you should know.

Now, on to your actual problem. The ldarg instruction loads a method argument. ldarg.2 is a shorthand-form for this, it's used to keep the code size small.
My advice would be for you to use the MethodBody.ExpandMacros() extension method is Mono.Rocks.dll when you begin working with a method, and MethodBody.SimplifyMacros() when you're done working with it.

ExpandMacros() will turn ldarg.2 (which doesn't have an operand, because it's a short form) to ldarg <ParameterReference>, which will now have an operand of type ParameterReference. That'll give you all the information you need.
SimplyMacros() will optimize the instructions again, and will use shorthand-forms whenever possible.

Hope this helps!

2011/7/5 rumpa.maji <rumpa...@socgen.com>
--
--
mono-cecil

Rumpa MAJI

unread,
Jul 6, 2011, 5:11:44 AM7/6/11
to mono-...@googlegroups.com

Hi,
Thank you for the reply. I tried with the following and it worked.

static class MethodEditor
    {
        static ParameterDefinition GetParameter(MethodBody self, int index)
        {
            MethodDefinition method = self.Method;

            if (method.HasThis)
            {
                if (index == 0)
                    return self.ThisParameter;

                index--;
            }

            return method.Parameters[index];
        }

        public static void SimplifyMacros(MethodBody self)
        {
            if (self == null) throw new ArgumentNullException("self");

            foreach (Instruction instruction in self.Instructions)
            {
                if (instruction.OpCode.OpCodeType != OpCodeType.Macro) continue;

                switch (instruction.OpCode.Code)
                {
                    case Code.Ldarg_0:
                        ExpandMacro(instruction, OpCodes.Ldarg, GetParameter(self, 0));
                        break;
                    case Code.Ldarg_1:
                        ExpandMacro(instruction, OpCodes.Ldarg, GetParameter(self, 1));
                        break;
                    case Code.Ldarg_2:
                        ExpandMacro(instruction, OpCodes.Ldarg, GetParameter(self, 2));
                        break;
                    case Code.Ldarg_3:
                        ExpandMacro(instruction, OpCodes.Ldarg, GetParameter(self, 3));
                        break;
                    case Code.Ldloc_0:
                        ExpandMacro(instruction, OpCodes.Ldloc, self.Variables[0]);
                        break;
                    case Code.Ldloc_1:
                        ExpandMacro(instruction, OpCodes.Ldloc, self.Variables[1]);
                        break;
                    case Code.Ldloc_2:
                        ExpandMacro(instruction, OpCodes.Ldloc, self.Variables[2]);
                        break;
                    case Code.Ldloc_3:
                        ExpandMacro(instruction, OpCodes.Ldloc, self.Variables[3]);
                        break;
                    case Code.Stloc_0:
                        ExpandMacro(instruction, OpCodes.Stloc, self.Variables[0]);
                        break;
                    case Code.Stloc_1:
                        ExpandMacro(instruction, OpCodes.Stloc, self.Variables[1]);
                        break;
                    case Code.Stloc_2:
                        ExpandMacro(instruction, OpCodes.Stloc, self.Variables[2]);
                        break;
                    case Code.Stloc_3:
                        ExpandMacro(instruction, OpCodes.Stloc, self.Variables[3]);
                        break;
                    case Code.Ldarg_S:
                        instruction.OpCode = OpCodes.Ldarg;
                        break;
                    case Code.Ldarga_S:
                        instruction.OpCode = OpCodes.Ldarga;
                        break;
                    case Code.Starg_S:
                        instruction.OpCode = OpCodes.Starg;
                        break;
                    case Code.Ldloc_S:
                        instruction.OpCode = OpCodes.Ldloc;
                        break;
                    case Code.Ldloca_S:
                        instruction.OpCode = OpCodes.Ldloca;
                        break;
                    case Code.Stloc_S:
                        instruction.OpCode = OpCodes.Stloc;
                        break;
                    case Code.Ldc_I4_M1:
                        ExpandMacro(instruction, OpCodes.Ldc_I4, -1);
                        break;
                    case Code.Ldc_I4_0:
                        ExpandMacro(instruction, OpCodes.Ldc_I4, 0);
                        break;
                    case Code.Ldc_I4_1:
                        ExpandMacro(instruction, OpCodes.Ldc_I4, 1);
                        break;
                    case Code.Ldc_I4_2:
                        ExpandMacro(instruction, OpCodes.Ldc_I4, 2);
                        break;
                    case Code.Ldc_I4_3:
                        ExpandMacro(instruction, OpCodes.Ldc_I4, 3);
                        break;
                    case Code.Ldc_I4_4:
                        ExpandMacro(instruction, OpCodes.Ldc_I4, 4);
                        break;
                    case Code.Ldc_I4_5:
                        ExpandMacro(instruction, OpCodes.Ldc_I4, 5);
                        break;
                    case Code.Ldc_I4_6:
                        ExpandMacro(instruction, OpCodes.Ldc_I4, 6);
                        break;
                    case Code.Ldc_I4_7:
                        ExpandMacro(instruction, OpCodes.Ldc_I4, 7);
                        break;
                    case Code.Ldc_I4_8:
                        ExpandMacro(instruction, OpCodes.Ldc_I4, 8);
                        break;
                    case Code.Ldc_I4_S:
                        ExpandMacro(instruction, OpCodes.Ldc_I4, (int)(sbyte)instruction.Operand);
                        break;
                    case Code.Br_S:
                        instruction.OpCode = OpCodes.Br;
                        break;
                    case Code.Brfalse_S:
                        instruction.OpCode = OpCodes.Brfalse;
                        break;
                    case Code.Brtrue_S:
                        instruction.OpCode = OpCodes.Brtrue;
                        break;
                    case Code.Beq_S:
                        instruction.OpCode = OpCodes.Beq;
                        break;
                    case Code.Bge_S:
                        instruction.OpCode = OpCodes.Bge;
                        break;
                    case Code.Bgt_S:
                        instruction.OpCode = OpCodes.Bgt;
                        break;
                    case Code.Ble_S:
                        instruction.OpCode = OpCodes.Ble;
                        break;
                    case Code.Blt_S:
                        instruction.OpCode = OpCodes.Blt;
                        break;
                    case Code.Bne_Un_S:
                        instruction.OpCode = OpCodes.Bne_Un;
                        break;
                    case Code.Bge_Un_S:
                        instruction.OpCode = OpCodes.Bge_Un;
                        break;
                    case Code.Bgt_Un_S:
                        instruction.OpCode = OpCodes.Bgt_Un;
                        break;
                    case Code.Ble_Un_S:
                        instruction.OpCode = OpCodes.Ble_Un;
                        break;
                    case Code.Blt_Un_S:
                        instruction.OpCode = OpCodes.Blt_Un;
                        break;
                    case Code.Leave_S:
                        instruction.OpCode = OpCodes.Leave;
                        break;
                }
            }
        }

        static void ExpandMacro(Instruction instruction, OpCode opcode, object operand)
        {
            instruction.OpCode = opcode;
            instruction.Operand = operand;
        }
    }

Regards
Rumpa Maji




kozar...@gmail.com
Sent by: mono-...@googlegroups.com

07/05/2011 07:23 PM

Please respond to
mono-...@googlegroups.com

To
mono-...@googlegroups.com
cc
Subject
Re: [mono-cecil] Reading the type the second argument passed toString.Format(string s, object obj) method using Mono.cecil


--
--
mono-cecil

*************************************************************************
This message and any attachments (the "message") are confidential, intended solely for the addressee(s), and may contain legally privileged information.
Any unauthorised use or dissemination is prohibited. E-mails are susceptible to alteration. 
Neither SOCIETE GENERALE nor any of its subsidiaries or affiliates shall be liable for the message if altered, changed or
falsified.
                              ************
Ce message et toutes les pieces jointes (ci-apres le "message") sont confidentiels et susceptibles de contenir des informations couvertes
par le secret professionnel.
Ce message est etabli a l'intention exclusive de ses destinataires. Toute utilisation ou diffusion non autorisee est interdite.
Tout message electronique est susceptible d'alteration.
La SOCIETE GENERALE et ses filiales declinent toute responsabilite au titre de ce message s'il a ete altere, deforme ou falsifie.
*************************************************************************

Gábor Kozár

unread,
Jul 6, 2011, 5:37:21 AM7/6/11
to mono-...@googlegroups.com
Glad I could be of help. :)
Just make sure you optimize the macros again when you're finished with the method, because it'll significantly reduce the code size.

2011/7/6 Rumpa MAJI <rumpa...@socgen.com>

--
--
mono-cecil

************************************************************************* --
--
mono-cecil


Reply all
Reply to author
Forward
0 new messages