public IEnumerable <IntPtr> JumpTargets()
        {
            var formatter = new IntelFormatter();
            var builder   = new StringBuilder();

            while (true)
            {
                myDecoder.Decode(out var instruction);
                builder.Clear();
                formatter.Format(in instruction, new StringOutput(builder));
                LogSupport.Trace($"Decoded instruction: {builder}");
                if (myDecoder.InvalidNoMoreBytes)
                {
                    yield break;
                }
                if (instruction.FlowControl == FlowControl.Return)
                {
                    yield break;
                }

                if (instruction.FlowControl == FlowControl.UnconditionalBranch || instruction.FlowControl == FlowControl.Call)
                {
                    yield return((IntPtr)ExtractTargetAddress(in instruction));

                    if (instruction.FlowControl == FlowControl.UnconditionalBranch)
                    {
                        yield break;
                    }
                }
            }
        }
Exemplo n.º 2
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());
            }
        }