Пример #1
0
        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);
            }
        }
Пример #2
0
        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);
            }
        }
Пример #3
0
 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()));
 }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }
Пример #6
0
        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));
            }
        }
Пример #7
0
        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));
                }
            }
        }
Пример #8
0
 /// <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));
Пример #9
0
        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);
        }
Пример #10
0
 /// <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());