public ILTryInfo GetTryInfo(int addr, out TryCodeType type) { type = TryCodeType.None; ILTryInfo last = null; int begin = -1; int end = -1; foreach (var info in tryInfos) { //check try first if (info.addr_Try_Begin <= addr && addr < info.addr_Try_End) { if (last == null) { type = TryCodeType.Try; last = info; begin = info.addr_Try_Begin; end = last.addr_Try_End; } else if (begin <= info.addr_Try_Begin && last.addr_Try_End < end) { type = TryCodeType.Try; last = info; begin = info.addr_Try_Begin; end = last.addr_Try_End; } } //then code in final but not in try if (info.addr_Try_Begin <= addr && addr < info.addr_Try_End_F) { if (last == null) { type = TryCodeType.Try_Final; last = info; begin = info.addr_Try_Begin; end = last.addr_Try_End_F; } else if (begin <= info.addr_Try_Begin && last.addr_Try_End_F < end) { type = TryCodeType.Try_Final; last = info; begin = info.addr_Try_Begin; end = last.addr_Try_End_F; } } //find match finally if (info.addr_Finally_Begin <= addr && addr < info.addr_Finally_End) { if (last == null) { type = TryCodeType.Final; last = info; begin = info.addr_Finally_Begin; end = last.addr_Finally_End; } else if (begin <= info.addr_Finally_Begin && last.addr_Finally_End < end) { type = TryCodeType.Final; last = info; begin = info.addr_Finally_Begin; end = last.addr_Finally_End; } } //find match catch foreach (var c in info.catch_Infos) { if (c.Value.addrBegin <= addr && addr < c.Value.addrEnd) { if (last == null) { type = TryCodeType.Catch; last = info; begin = c.Value.addrBegin; end = c.Value.addrEnd; } else if (begin <= c.Value.addrBegin && c.Value.addrBegin < end) { type = TryCodeType.Catch; last = info; begin = c.Value.addrBegin; end = c.Value.addrEnd; } } } } return(last); }
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); } } } } } }