Пример #1
0
        private void WriteIgnoredOpenGeneric(JitWriteContext context, MethodBase method)
        {
            WriteSignatureFromReflection(context, method);
            var writer = context.Writer;

            writer.WriteLine("    ; Open generics cannot be JIT-compiled.");
        }
Пример #2
0
        private void DisassembleAndWriteMembers(JitWriteContext context, TypeInfo type, ImmutableArray <Type>?genericArgumentTypes = null)
        {
            if (type.IsGenericTypeDefinition)
            {
                if (TryDisassembleAndWriteMembersOfGeneric(context, type, genericArgumentTypes))
                {
                    return;
                }
            }

            foreach (var constructor in type.DeclaredConstructors)
            {
                DisassembleAndWriteMethod(context, constructor);
            }

            foreach (var method in type.DeclaredMethods)
            {
                if (method.IsAbstract)
                {
                    continue;
                }
                DisassembleAndWriteMethod(context, method);
            }

            foreach (var nested in type.DeclaredNestedTypes)
            {
                DisassembleAndWriteMembers(context, nested, genericArgumentTypes);
            }
        }
Пример #3
0
        private static void WriteSignatureFromReflection(JitWriteContext context, MethodBase method)
        {
            context.Writer.WriteLine();

            var md        = (ulong)method.MethodHandle.Value.ToInt64();
            var signature = context.Runtime.DacLibrary.SOSDacInterface.GetMethodDescName(md);

            context.Writer.WriteLine(signature ?? "Unknown Method");
        }
Пример #4
0
        private bool TryDisassembleAndWriteMembersOfGeneric(JitWriteContext context, TypeInfo type, ImmutableArray <Type>?parentArgumentTypes = null)
        {
            if (parentArgumentTypes is not null)
            {
                var genericInstance = type.MakeGenericType(parentArgumentTypes.Value.ToArray());
                DisassembleAndWriteMembers(context, genericInstance.GetTypeInfo(), parentArgumentTypes);
                return(true);
            }

            return(false);
        }
Пример #5
0
        private void DisassembleAndWriteMethod(JitWriteContext context, MethodBase method)
        {
            if ((method.MethodImplementationFlags & MethodImplAttributes.Runtime) == MethodImplAttributes.Runtime)
            {
                WriteSignatureFromReflection(context, method);
                context.Writer.WriteLine("    ; Cannot produce JIT assembly for runtime-implemented method.");
                return;
            }

            if (method.DeclaringType?.IsGenericTypeDefinition ?? false)
            {
                WriteIgnoredOpenGeneric(context, method);
                return;
            }

            if (method.IsGenericMethodDefinition)
            {
                DisassembleAndWriteGenericMethod(context, (MethodInfo)method);
                return;
            }

            DisassembleAndWriteSimpleMethod(context, method);
        }
Пример #6
0
        private void Decompile(Stream dll, TextWriter codeWriter)
        {
            using (var loadContext = new CustomAssemblyLoadContext(shouldShareAssembly: _ => true))
            {
                var assembly = loadContext.LoadFromStream(dll);
                ValidateStaticConstructors(assembly);

                using var runtimeLease = _runtimePool.GetOrCreate();
                var runtime = runtimeLease.Object;
                runtime.Flush();

                var context = new JitWriteContext(codeWriter, runtime);

                WriteJitInfo(runtime.ClrInfo, codeWriter);
                foreach (var type in assembly.DefinedTypes)
                {
                    if (type.IsNested)
                    {
                        continue; // it's easier to handle nested generic types recursively, so we suppress all nested for consistency
                    }
                    DisassembleAndWriteMembers(context, type);
                }
            }
        }
Пример #7
0
        private void DisassembleAndWriteSimpleMethod(JitWriteContext context, MethodBase method)
        {
            var handle = method.MethodHandle;

            RuntimeHelpers.PrepareMethod(handle);

            var clrMethod = context.Runtime.GetMethodByHandle((ulong)handle.Value.ToInt64());
            var regions   = FindNonEmptyHotColdInfo(clrMethod);

            if (clrMethod is null || regions is null)
            {
                context.Runtime.Flush();
                clrMethod = context.Runtime.GetMethodByHandle((ulong)handle.Value.ToInt64());
                regions   = FindNonEmptyHotColdInfo(clrMethod);
            }

            if (clrMethod is null || regions is null)
            {
                var address = (ulong)handle.GetFunctionPointer().ToInt64();
                clrMethod = context.Runtime.GetMethodByAddress(address);
                regions   = FindNonEmptyHotColdInfo(clrMethod);
            }

            var writer = context.Writer;

            if (clrMethod is not null)
            {
                writer.WriteLine();
                writer.WriteLine(clrMethod.GetFullSignature());
            }
            else
            {
                WriteSignatureFromReflection(context, method);
            }

            if (regions is null)
            {
                if (method.IsGenericMethod || (method.DeclaringType?.IsGenericType ?? false))
                {
                    writer.WriteLine("    ; Failed to find HotColdInfo for generic method (reference types?).");
                    return;
                }
                writer.WriteLine("    ; Failed to find HotColdRegions.");
                return;
            }

            var methodAddress = regions.HotStart;
            var methodLength  = regions.HotSize;

            var reader  = new MemoryCodeReader(new IntPtr(unchecked ((long)methodAddress)), methodLength);
            var decoder = Decoder.Create(MapArchitectureToBitness(context.Runtime.DataTarget.Architecture), reader);

            var instructions = new InstructionList();

            decoder.IP = methodAddress;
            while (decoder.IP < (methodAddress + methodLength))
            {
                decoder.Decode(out instructions.AllocUninitializedElement());
            }

            var resolver  = new JitAsmSymbolResolver(context.Runtime, methodAddress, methodLength);
            var formatter = new IntelFormatter(FormatterOptions, resolver);
            var output    = new StringOutput();

            foreach (ref var instruction in instructions)
            {
                formatter.Format(instruction, output);

                writer.Write("    L");
                writer.Write((instruction.IP - methodAddress).ToString("x4"));
                writer.Write(": ");
                writer.WriteLine(output.ToStringAndReset());
            }
        }
Пример #8
0
 private void DisassembleAndWriteGenericMethod(JitWriteContext context, MethodInfo method) => WriteIgnoredOpenGeneric(context, method);