Mono.Debugger.Architectures.Architecture_X86_64.try_unwind_sigreturn C# (CSharp) Method

try_unwind_sigreturn() private method

private try_unwind_sigreturn ( StackFrame frame, TargetMemoryAccess memory ) : StackFrame
frame StackFrame
memory TargetMemoryAccess
return StackFrame
        StackFrame try_unwind_sigreturn(StackFrame frame, TargetMemoryAccess memory)
        {
            byte[] data = memory.ReadMemory (frame.TargetAddress, 9).Contents;

            /*
             * Check for signal return trampolines:
             *
             *   mov __NR_rt_sigreturn, %eax
             *   syscall
             */
            if ((data [0] != 0x48) || (data [1] != 0xc7) ||
                (data [2] != 0xc0) || (data [3] != 0x0f) ||
                (data [4] != 0x00) || (data [5] != 0x00) ||
                (data [6] != 0x00) || (data [7] != 0x0f) ||
                (data [8] != 0x05))
                return null;

            TargetAddress stack = frame.StackPointer;
            /* See `struct sigcontext' in <asm/sigcontext.h> */
            int[] regoffsets = {
                (int) X86_Register.R8,  (int) X86_Register.R9,
                (int) X86_Register.R10, (int) X86_Register.R11,
                (int) X86_Register.R12, (int) X86_Register.R13,
                (int) X86_Register.R14, (int) X86_Register.R15,
                (int) X86_Register.RDI, (int) X86_Register.RSI,
                (int) X86_Register.RBP, (int) X86_Register.RBX,
                (int) X86_Register.RDX, (int) X86_Register.RAX,
                (int) X86_Register.RCX, (int) X86_Register.RSP,
                (int) X86_Register.RIP, (int) X86_Register.EFLAGS
            };

            Registers regs = CopyRegisters (frame.Registers);

            int offset = 0x28;
            /* The stack contains the `struct ucontext' from <asm/ucontext.h>; the
             * `struct sigcontext' starts at offset 0x28 in it. */
            foreach (int regoffset in regoffsets) {
                TargetAddress new_value = memory.ReadAddress (stack + offset);
                regs [regoffset].SetValue (new_value);
                offset += 8;
            }

            TargetAddress rip = new TargetAddress (
                memory.AddressDomain, regs [(int) X86_Register.RIP].GetValue ());
            TargetAddress rsp = new TargetAddress (
                memory.AddressDomain, regs [(int) X86_Register.RSP].GetValue ());
            TargetAddress rbp = new TargetAddress (
                memory.AddressDomain, regs [(int) X86_Register.RBP].GetValue ());

            Symbol name = new Symbol ("<signal handler>", rip, 0);

            return new StackFrame (
                frame.Thread, FrameType.Signal, rip, rsp, rbp, regs, frame.Thread.NativeLanguage, name);
        }