static private void debugMethod(Mono.Cecil.TypeDefinition type, Mono.Cecil.AssemblyDefinition assembly, string prefix = "") { nestSearch(type, assembly, ref prefix, debugMethod); type.Methods.ToList().ForEach((method) => { var il = method.Body.GetILProcessor(); var module = type.Module; var write = il.Create( Mono.Cecil.Cil.OpCodes.Call, module.Import(typeof(Console).GetMethod("WriteLine", new[] { typeof(object) }))); var ret = il.Create(Mono.Cecil.Cil.OpCodes.Ret); var leave = il.Create(Mono.Cecil.Cil.OpCodes.Leave, ret); il.InsertAfter( method.Body.Instructions.Last(), write); il.InsertAfter(write, leave); il.InsertAfter(leave, ret); var handler = new Mono.Cecil.Cil.ExceptionHandler(Mono.Cecil.Cil.ExceptionHandlerType.Catch) { TryStart = method.Body.Instructions.First(), TryEnd = write, HandlerStart = write, HandlerEnd = ret, CatchType = module.Import(typeof(Exception)), }; method.Body.ExceptionHandlers.Add(handler); }); }
private void CreateExceptionHandlers(IDictionary <Model.Bytecode.Instruction, IList <Mono.Cecil.Cil.Instruction> > map, AnalysisNet.Types.MethodBody analysisNetBody, Cecil.Cil.MethodBody cecilBody) { foreach (AnalysisNet.ProtectedBlock protectedBlock in analysisNetBody.ExceptionInformation) { Cecil.Cil.ExceptionHandler handler = new Cecil.Cil.ExceptionHandler(GetExceptionHandlerType(protectedBlock.Handler.Kind)) { TryStart = GetTarget(protectedBlock.Start, map), TryEnd = GetTarget(protectedBlock.End, map) }; if (protectedBlock.Handler is AnalysisNet.FilterExceptionHandler filterHandler) { handler.CatchType = ReferenceGenerator.TypeReference(filterHandler.ExceptionType); handler.FilterStart = GetTarget(filterHandler.FilterStart, map); handler.HandlerStart = GetTarget(filterHandler.Start, map); handler.HandlerEnd = GetTarget(filterHandler.End, map); } else if (protectedBlock.Handler is AnalysisNet.CatchExceptionHandler catchHandler) { handler.CatchType = ReferenceGenerator.TypeReference(catchHandler.ExceptionType); handler.HandlerStart = GetTarget(catchHandler.Start, map); handler.HandlerEnd = GetTarget(catchHandler.End, map); } else if (protectedBlock.Handler is AnalysisNet.FaultExceptionHandler faultHandler) { handler.HandlerStart = GetTarget(faultHandler.Start, map); handler.HandlerEnd = GetTarget(faultHandler.End, map); } else if (protectedBlock.Handler is AnalysisNet.FinallyExceptionHandler finallyHandler) { handler.HandlerStart = GetTarget(finallyHandler.Start, map); handler.HandlerEnd = GetTarget(finallyHandler.End, map); } else { throw new NotImplementedException(); } cecilBody.ExceptionHandlers.Add(handler); } }
public static void WriteTo(this ILExceptionHandler exceptionHandler, ITextOutput writer) { writer.Write("Try "); WriteOffsetReference(writer, exceptionHandler.TryStart); writer.Write('-'); WriteOffsetReference(writer, exceptionHandler.TryEnd); writer.Write(' '); writer.Write(exceptionHandler.HandlerType.ToString()); if (exceptionHandler.FilterStart != null) { writer.Write(' '); WriteOffsetReference(writer, exceptionHandler.FilterStart); writer.Write(" handler "); } if (exceptionHandler.CatchType != null) { writer.Write(' '); exceptionHandler.CatchType.WriteTo(writer); } writer.Write(' '); WriteOffsetReference(writer, exceptionHandler.HandlerStart); writer.Write('-'); WriteOffsetReference(writer, exceptionHandler.HandlerEnd); }
private void Emit(CilCodegenInstruction instruction) { if (instruction is CilMarkTargetInstruction) { pendingTargets.Add(((CilMarkTargetInstruction)instruction).Target); } else if (instruction is CilOpInstruction) { var opInsn = (CilOpInstruction)instruction; // Emit the instruction. Emit(opInsn.Op); // Add an entry to the patch list if necessary. if (opInsn.Patch != null) { patches.Add(opInsn); } } else if (instruction is CilExceptionHandlerInstruction) { var handlerInsn = (CilExceptionHandlerInstruction)instruction; // Create the actual exception handler. var handler = new Mono.Cecil.Cil.ExceptionHandler(handlerInsn.Type); if (handlerInsn.Type == Mono.Cecil.Cil.ExceptionHandlerType.Catch) { handler.CatchType = handlerInsn.CatchType; } Processor.Body.ExceptionHandlers.Add(handler); // Emit the try block's contents. Record the last instruction // prior to the try block. We'll use it to find the first instruction // inside the try block when we add a handler to the var preTryInstruction = Processor.Body.Instructions.LastOrDefault(); foreach (var insn in handlerInsn.TryBlock) { Emit(insn); } // Similarly, record the last instruction of the 'try' block and then // proceed by emitting the handler block. var lastTryInstruction = Processor.Body.Instructions.LastOrDefault(); foreach (var insn in handlerInsn.HandlerBlock) { Emit(insn); } // Populate the exception handler's start/end fields. handler.TryStart = preTryInstruction == null ? Processor.Body.Instructions.First() : preTryInstruction.Next; handler.TryEnd = lastTryInstruction == null ? Processor.Body.Instructions.First() : lastTryInstruction.Next; handler.HandlerStart = handler.TryEnd; handler.HandlerEnd = Processor.Create(OpCodes.Nop); Processor.Append(handler.HandlerEnd); } else if (instruction is CilLoadRegisterInstruction) { var loadInsn = (CilLoadRegisterInstruction)instruction; var reg = RegisterAllocation.GetRegister(loadInsn.Value); if (reg.IsParameter) { Emit(CilInstruction.Create(OpCodes.Ldarg, reg.ParameterOrNull)); } else { IncrementUseCount(reg.VariableOrNull); Emit(CilInstruction.Create(OpCodes.Ldloc, reg.VariableOrNull)); } } else if (instruction is CilAddressOfRegisterInstruction) { var addressOfInsn = (CilAddressOfRegisterInstruction)instruction; var reg = RegisterAllocation.GetRegister(addressOfInsn.Value); if (reg.IsParameter) { Emit(CilInstruction.Create(OpCodes.Ldarga, reg.ParameterOrNull)); } else { IncrementUseCount(reg.VariableOrNull); Emit(CilInstruction.Create(OpCodes.Ldloca, reg.VariableOrNull)); } } else { var storeInsn = (CilStoreRegisterInstruction)instruction; if (RegisterAllocation.Allocation.ContainsKey(storeInsn.Value)) { var reg = RegisterAllocation.GetRegister(storeInsn.Value); if (reg.IsParameter) { Emit(CilInstruction.Create(OpCodes.Starg, reg.ParameterOrNull)); } else { IncrementUseCount(reg.VariableOrNull); Emit(CilInstruction.Create(OpCodes.Stloc, reg.VariableOrNull)); } } else { Emit(CilInstruction.Create(OpCodes.Pop)); } } }
protected override void Visit(Mono.Cecil.Cil.ExceptionHandler exceptionHandler, Context context) { Touch(exceptionHandler); base.Visit(exceptionHandler, context); }
public ILMethod(ILType type, Mono.Cecil.MethodDefinition method, ILogger logger = null) { this.type = type; this.method = method; if (method != null) { returntype = method.ReturnType.FullName; if (method.HasParameters) { hasParam = true; foreach (var p in method.Parameters) { string paramtype = p.ParameterType.FullName; try { var _type = p.ParameterType.Resolve(); foreach (var i in _type.Interfaces) { if (i.InterfaceType.Name == "IApiInterface") { paramtype = "IInteropInterface"; } } } catch { } this.paramtypes.Add(new NeoParam(p.Name, paramtype)); } } if (method.HasBody) { var bodyNative = method.Body; if (bodyNative.HasVariables) { foreach (var v in bodyNative.Variables) { var indexname = v.VariableType.Name + ":" + v.Index; this.body_Variables.Add(new NeoParam(indexname, v.VariableType.FullName)); } } for (int i = 0; i < bodyNative.Instructions.Count; i++) { var code = bodyNative.Instructions[i]; OpCode c = new OpCode { code = (CodeEx)(int)code.OpCode.Code, addr = code.Offset }; var sp = method.DebugInformation.GetSequencePoint(code); if (sp != null) { c.debugcode = sp.Document.Url; c.debugline = sp.StartLine; } c.InitToken(code.Operand); this.body_Codes.Add(c.addr, c); } if (method.Body.HasExceptionHandlers) { var mapTryInfos = new Dictionary <string, ILTryInfo>(); foreach (var e in method.Body.ExceptionHandlers) { if (e.HandlerType == Mono.Cecil.Cil.ExceptionHandlerType.Catch) { var key = e.TryStart.Offset + "_" + e.TryEnd.Offset; if (mapTryInfos.ContainsKey(key) == false) { mapTryInfos[key] = new ILTryInfo(); } var tryinfo = mapTryInfos[key]; tryinfo.addr_Try_Begin = e.TryStart.Offset; tryinfo.addr_Try_End = e.TryEnd.Offset; var catchtypestr = e.CatchType.FullName; tryinfo.catch_Infos[catchtypestr] = new ILCatchInfo() { addrBegin = e.HandlerStart.Offset, addrEnd = e.HandlerEnd.Offset, catchType = catchtypestr }; } else if (e.HandlerType == Mono.Cecil.Cil.ExceptionHandlerType.Finally) { int start = e.TryStart.Offset; int end = e.TryEnd.Offset; Mono.Cecil.Cil.ExceptionHandler handler = null; foreach (var tryinfocatch in method.Body.ExceptionHandlers) { if (tryinfocatch.HandlerType == Mono.Cecil.Cil.ExceptionHandlerType.Catch && tryinfocatch.TryStart.Offset == e.TryStart.Offset && tryinfocatch.TryEnd.Offset <= e.TryEnd.Offset) {//find include catch element. if (handler == null) { handler = tryinfocatch; } else if (handler.TryEnd.Offset < tryinfocatch.TryEnd.Offset) { handler = tryinfocatch; } } } if (handler != null) { start = handler.TryStart.Offset; end = handler.TryEnd.Offset; } var key = start + "_" + end; if (mapTryInfos.ContainsKey(key) == false) { mapTryInfos[key] = new ILTryInfo(); } var tryinfo = mapTryInfos[key]; tryinfo.addr_Try_Begin = start; tryinfo.addr_Try_End = end; tryinfo.addr_Try_End_F = e.TryEnd.Offset; tryinfo.addr_Finally_Begin = e.HandlerStart.Offset; tryinfo.addr_Finally_End = e.HandlerEnd.Offset; } else { throw new Exception("not support yet." + e.HandlerType); } } this.tryInfos = new List <ILTryInfo>(mapTryInfos.Values); foreach (var info in this.tryInfos) { if (this.tryPositions.Contains(info.addr_Try_Begin) == false) { this.tryPositions.Add(info.addr_Try_Begin); } } } } } }
public CilHandlerStartMarker(Mono.Cecil.Cil.ExceptionHandler handler) { this.Handler = handler; }