public void MethodHandleMultiDomainTests() { ulong[] methodDescs; using (DataTarget dt = TestTargets.AppDomains.LoadFullDump()) { ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrModule module = runtime.GetModule("sharedlibrary.dll"); ClrType type = module.GetTypeByName("Foo"); ClrMethod method = type.GetMethod("Bar"); methodDescs = method.EnumerateMethodDescs().ToArray(); Assert.AreEqual(2, methodDescs.Length); } using (DataTarget dt = TestTargets.AppDomains.LoadFullDump()) { ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrMethod method = runtime.GetMethodByHandle(methodDescs[0]); Assert.IsNotNull(method); Assert.AreEqual("Bar", method.Name); Assert.AreEqual("Foo", method.Type.Name); } using (DataTarget dt = TestTargets.AppDomains.LoadFullDump()) { ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrMethod method = runtime.GetMethodByHandle(methodDescs[1]); Assert.IsNotNull(method); Assert.AreEqual("Bar", method.Name); Assert.AreEqual("Foo", method.Type.Name); } }
public void MethodHandleMultiDomainTests() { ulong[] methodDescs; using (DataTarget dt = TestTargets.AppDomains.LoadFullDump()) { using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrType[] types = runtime.EnumerateModules().Where(m => m.Name.EndsWith("sharedlibrary.dll", System.StringComparison.OrdinalIgnoreCase)).Select(m => m.GetTypeByName("Foo")).Where(t => t != null).ToArray(); Assert.Equal(2, types.Length); methodDescs = types.Select(t => t.Methods.Single(m => m.Name == "Bar")).Select(m => m.MethodDesc).ToArray(); Assert.Equal(2, methodDescs.Length); } using (DataTarget dt = TestTargets.AppDomains.LoadFullDump()) { using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrMethod method = runtime.GetMethodByHandle(methodDescs[0]); Assert.NotNull(method); Assert.Equal("Bar", method.Name); Assert.Equal("Foo", method.Type.Name); } using (DataTarget dt = TestTargets.AppDomains.LoadFullDump()) { using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrMethod method = runtime.GetMethodByHandle(methodDescs[1]); Assert.NotNull(method); Assert.Equal("Bar", method.Name); Assert.Equal("Foo", method.Type.Name); } }
private static ClrMethod GetMethod(ClrRuntime runtime, Remote.MethodJitResult result) { if (result.Pointer == null) { return(runtime.GetMethodByHandle((ulong)result.Handle.ToInt64())); } return(runtime.GetMethodByAddress((ulong)result.Pointer.Value.ToInt64())); }
public unsafe (ulong codePointer, uint codeSize) GetMethodAddress(ClrRuntime runtime, MethodInfo method) { var clrmdMethodHandle = runtime.GetMethodByHandle((ulong)method.MethodHandle.Value.ToInt64()); if (clrmdMethodHandle.NativeCode == 0) { throw new InvalidOperationException($"Unable to disassemble method `{method}`"); } var codePtr = clrmdMethodHandle.HotColdInfo.HotStart; var codeSize = clrmdMethodHandle.HotColdInfo.HotSize; return(codePtr, codeSize); }
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); }
public void MethodHandleSingleDomainTests() { ulong methodDesc; using (DataTarget dt = TestTargets.Types.LoadFullDump()) { using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrModule module = runtime.GetModule("sharedlibrary.dll"); ClrType type = module.GetTypeByName("Foo"); ClrMethod method = type.GetMethod("Bar"); methodDesc = method.MethodDesc; Assert.NotEqual(0ul, methodDesc); } using (DataTarget dt = TestTargets.Types.LoadFullDump()) { using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrMethod method = runtime.GetMethodByHandle(methodDesc); Assert.NotNull(method); Assert.Equal("Bar", method.Name); Assert.Equal("Foo", method.Type.Name); } using (DataTarget dt = TestTargets.Types.LoadFullDump()) { using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrModule module = runtime.GetModule("sharedlibrary.dll"); ClrType type = module.GetTypeByName("Foo"); ClrMethod method = type.GetMethod("Bar"); Assert.Equal(methodDesc, method.MethodDesc); Assert.Equal(method, runtime.GetMethodByHandle(methodDesc)); } }
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)); } } }
/// <summary> /// Returns a ClrMethod by its internal runtime handle (on desktop CLR this is a MethodDesc). /// </summary> /// <param name="methodHandle">The method handle (MethodDesc) to look up.</param> /// <returns>The ClrMethod for the given method handle, or null if no method was found.</returns> /// <inheritdoc /> public IClrMethod GetMethodByHandle(ulong methodHandle) => Converter.Convert(Runtime.GetMethodByHandle(methodHandle));
private bool GetReferencedAddressToMethodName(out ulong refAddress, out uint codeSize, out string name, Instruction instruction, ClrRuntime runtime) { name = null; refAddress = 0; codeSize = 0; bool isAddressOk = false; for (int i = 0; i < instruction.OpCount; i++) { switch (instruction.GetOpKind(i)) { case OpKind.NearBranch16: case OpKind.NearBranch32: case OpKind.NearBranch64: refAddress = instruction.NearBranchTarget; isAddressOk = refAddress > ushort.MaxValue; break; case OpKind.Immediate64: refAddress = instruction.GetImmediate(i); isAddressOk = refAddress > ushort.MaxValue; break; case OpKind.Memory64: refAddress = instruction.MemoryAddress64; isAddressOk = refAddress > ushort.MaxValue; break; case OpKind.Memory when instruction.IsIPRelativeMemoryOperand: refAddress = instruction.IPRelativeMemoryAddress; isAddressOk = refAddress > ushort.MaxValue; break; case OpKind.Memory: refAddress = instruction.MemoryDisplacement; isAddressOk = refAddress > ushort.MaxValue; break; } } if (refAddress == 0) { return(false); } var jitHelperFunctionName = runtime.GetJitHelperFunctionName(refAddress); if (string.IsNullOrWhiteSpace(jitHelperFunctionName) == false) { name = jitHelperFunctionName; return(true); } var methodTableName = runtime.GetMethodTableName(refAddress); if (string.IsNullOrWhiteSpace(methodTableName) == false) { name = methodTableName; return(true); } var methodDescriptor = runtime.GetMethodByHandle(refAddress); if (methodDescriptor != null) { name = methodDescriptor.Name; refAddress = methodDescriptor.HotColdInfo.HotStart; codeSize = methodDescriptor.HotColdInfo.HotSize; return(true); } var methodCall = runtime.GetMethodByAddress(refAddress); if (methodCall != null && string.IsNullOrWhiteSpace(methodCall.Name) == false) { name = methodCall.Name; refAddress = methodCall.HotColdInfo.HotStart; codeSize = methodCall.HotColdInfo.HotSize; return(true); } if (methodCall == null) { if (runtime.ReadPointer(refAddress, out ulong newAddress) && newAddress > ushort.MaxValue) { methodCall = runtime.GetMethodByAddress(newAddress); } if (methodCall is null) { return(false); } name = methodCall.Name; refAddress = methodCall.HotColdInfo.HotStart; codeSize = methodCall.HotColdInfo.HotSize; return(true); } return(false); }
/// <summary> /// Queries the runtime for the runtime method corresponding to a supplied <see cref='MethodInfo'/> /// </summary> /// <param name="rt">The source runtime</param> /// <param name="src">The represented method</param> ClrMethod GetRuntimeMethod(MethodBase src) => Runtime.GetMethodByHandle((ulong)src.MethodHandle.Value.ToInt64());