private ClrMethodData?FindJitCompiledMethod(ClrRuntime runtime, MethodJitResult result) { var sos = runtime.DacLibrary.SOSDacInterface; var methodDescAddress = unchecked ((ulong)result.Handle.ToInt64()); if (!sos.GetMethodDescData(methodDescAddress, 0, out var methodDesc)) { return(null); } return(GetJitCompiledMethodByMethodDescIfValid(sos, methodDesc) ?? FindJitCompiledMethodInMethodTable(sos, methodDesc)); }
private void DisassembleAndWrite(MethodJitResult result, ClrRuntime runtime, ArchitectureMode architecture, Translator translator, Reference <ulong> methodAddressRef, TextWriter writer) { var(method, regions) = ResolveJitResult(runtime, result); if (method == null) { writer.WriteLine("Unknown (0x{0:X})", (ulong)result.Handle.ToInt64()); writer.WriteLine(" ; Method was not found by CLRMD (reason unknown)."); writer.WriteLine(" ; See https://github.com/ashmind/SharpLab/issues/84."); return; } writer.WriteLine(method.GetFullSignature()); switch (result.Status) { case MethodJitStatus.IgnoredRuntime: writer.WriteLine(" ; Cannot produce JIT assembly for runtime-implemented method."); return; case MethodJitStatus.IgnoredOpenGenericWithNoAttribute: writer.WriteLine(" ; Open generics cannot be JIT-compiled."); writer.WriteLine(" ; However you can use attribute SharpLab.Runtime.JitGeneric to specify argument types."); writer.WriteLine(" ; Example: [JitGeneric(typeof(int)), JitGeneric(typeof(string))] void M<T>() { ... }."); return; } if (regions == null) { if (result.Status == MethodJitStatus.SuccessGeneric) { writer.WriteLine(" ; Failed to find HotColdInfo for generic method (reference types?)."); writer.WriteLine(" ; If you know a solution, please comment at https://github.com/ashmind/SharpLab/issues/99."); return; } writer.WriteLine(" ; Failed to find HotColdRegions — please report at https://github.com/ashmind/SharpLab/issues."); return; } var methodAddress = regions.HotStart; methodAddressRef.Value = methodAddress; using (var disasm = new Disassembler(new IntPtr(unchecked ((long)methodAddress)), (int)regions.HotSize, architecture, methodAddress)) { foreach (var instruction in disasm.Disassemble()) { writer.Write(" L"); writer.Write((instruction.Offset - methodAddress).ToString("x4")); writer.Write(": "); writer.WriteLine(translator.Translate(instruction)); } } }
private (ClrMethod?method, HotColdRegions?regions) ResolveJitResult(ClrRuntime runtime, MethodJitResult result) { ClrMethod?methodByPointer = null; if (result.Pointer != null) { methodByPointer = runtime.GetMethodByAddress((ulong)result.Pointer.Value.ToInt64()); if (methodByPointer != null) { if (!result.IsSuccess) { return(methodByPointer, null); } var regionsByPointer = FindNonEmptyHotColdInfo(methodByPointer); if (regionsByPointer != null) { return(methodByPointer, regionsByPointer); } } } var methodByHandle = runtime.GetMethodByHandle((ulong)result.Handle.ToInt64()); if (methodByHandle == null) { return(methodByPointer, null); } if (!result.IsSuccess) { return(methodByHandle, null); } var regionsByHandle = FindNonEmptyHotColdInfo(methodByHandle); if (regionsByHandle == null && methodByPointer != null) { return(methodByPointer, null); } return(methodByHandle, regionsByHandle); }
private void DisassembleAndWrite(MethodJitResult result, ClrRuntime runtime, ArchitectureMode architecture, Translator translator, Reference <ulong> methodAddressRef, TextWriter writer) { void WriteSignatureFromClrMethod() { var signature = runtime.GetMethodByHandle(unchecked ((ulong)result.Handle.ToInt64()))?.Signature; WriteSignature(signature); } void WriteSignature(string?signature) { if (signature != null) { writer.WriteLine(signature); } else { writer.WriteLine("Unknown (0x{0:X})", (ulong)result.Handle.ToInt64()); writer.WriteLine(" ; Method signature was not found -- please report this issue."); } } switch (result.Status) { case MethodJitStatus.IgnoredRuntime: WriteSignatureFromClrMethod(); writer.WriteLine(" ; Cannot produce JIT assembly for runtime-implemented method."); return; case MethodJitStatus.IgnoredOpenGenericWithNoAttribute: WriteSignatureFromClrMethod(); writer.WriteLine(" ; Open generics cannot be JIT-compiled."); writer.WriteLine(" ; However you can use attribute SharpLab.Runtime.JitGeneric to specify argument types."); writer.WriteLine(" ; Example: [JitGeneric(typeof(int)), JitGeneric(typeof(string))] void M<T>() { ... }."); return; } if (FindJitCompiledMethod(runtime, result) is not { } method) { WriteSignatureFromClrMethod(); if (result.Status == MethodJitStatus.SuccessGeneric) { writer.WriteLine(" ; Failed to find JIT output for generic method (reference types?)."); writer.WriteLine(" ; If you know a solution, please comment at https://github.com/ashmind/SharpLab/issues/99."); return; } writer.WriteLine(" ; Failed to find JIT output — please report at https://github.com/ashmind/SharpLab/issues."); return; } WriteSignature(method.Signature); var methodAddress = method.MethodAddress; methodAddressRef.Value = methodAddress; using (var disasm = new Disassembler(new IntPtr(unchecked ((long)methodAddress)), (int)method.MethodSize, architecture, methodAddress)) { foreach (var instruction in disasm.Disassemble()) { writer.Write(" L"); writer.Write((instruction.Offset - methodAddress).ToString("x4")); writer.Write(": "); writer.WriteLine(translator.Translate(instruction)); } } }