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

unwind_method() private method

private unwind_method ( StackFrame frame, TargetMemoryAccess memory, byte code, int pos, int offset ) : StackFrame
frame StackFrame
memory TargetMemoryAccess
code byte
pos int
offset int
return StackFrame
        StackFrame unwind_method(StackFrame frame, TargetMemoryAccess memory, byte[] code,
					  int pos, int offset)
        {
            Registers old_regs = frame.Registers;
            Registers regs = CopyRegisters (old_regs);

            if (!old_regs [(int) X86_Register.RBP].Valid)
                return null;

            TargetAddress rbp = new TargetAddress (
                memory.AddressDomain, old_regs [(int) X86_Register.RBP].Value);

            int addr_size = TargetAddressSize;
            TargetAddress new_rbp = memory.ReadAddress (rbp);
            regs [(int) X86_Register.RBP].SetValue (rbp, new_rbp);

            TargetAddress new_rip = memory.ReadAddress (rbp + addr_size);
            regs [(int) X86_Register.RIP].SetValue (rbp + addr_size, new_rip);

            TargetAddress new_rsp = rbp + 2 * addr_size;
            regs [(int) X86_Register.RSP].SetValue (rbp, new_rsp);

            rbp -= addr_size;

            int length = System.Math.Min (code.Length, offset);
            while (pos < length) {
                byte opcode = code [pos++];

                long value;
                if ((opcode == 0x41) && (pos < length)) {
                    byte opcode2 = code [pos++];

                    if ((opcode2 < 0x50) || (opcode2 > 0x57))
                        break;

                    switch (opcode2) {
                    case 0x50: /* r8 */
                        value = memory.ReadLongInteger (rbp);
                        regs [(int) X86_Register.R8].SetValue (rbp, value);
                        break;
                    case 0x51: /* r9 */
                        value = memory.ReadLongInteger (rbp);
                        regs [(int) X86_Register.R9].SetValue (rbp, value);
                        break;
                    case 0x52: /* r10 */
                        value = memory.ReadLongInteger (rbp);
                        regs [(int) X86_Register.R10].SetValue (rbp, value);
                        break;
                    case 0x53: /* r11 */
                        value = memory.ReadLongInteger (rbp);
                        regs [(int) X86_Register.R11].SetValue (rbp, value);
                        break;
                    case 0x54: /* r12 */
                        value = (long) memory.ReadAddress (rbp).Address;
                        regs [(int) X86_Register.R12].SetValue (rbp, value);
                        break;
                    case 0x55: /* r13 */
                        value = memory.ReadLongInteger (rbp);
                        regs [(int) X86_Register.R13].SetValue (rbp, value);
                        break;
                    case 0x56: /* r14 */
                        value = memory.ReadLongInteger (rbp);
                        regs [(int) X86_Register.R14].SetValue (rbp, value);
                        break;
                    case 0x57: /* r15 */
                        value = memory.ReadLongInteger (rbp);
                        regs [(int) X86_Register.R15].SetValue (rbp, value);
                        break;
                    }
                } else {
                    if ((opcode < 0x50) || (opcode > 0x57))
                        break;

                    switch (opcode) {
                    case 0x50: /* rax */
                        value = memory.ReadLongInteger (rbp);
                        regs [(int) X86_Register.RAX].SetValue (rbp, value);
                        break;
                    case 0x51: /* rcx */
                        value = memory.ReadLongInteger (rbp);
                        regs [(int) X86_Register.RCX].SetValue (rbp, value);
                        break;
                    case 0x52: /* rdx */
                        value = memory.ReadLongInteger (rbp);
                        regs [(int) X86_Register.RDX].SetValue (rbp, value);
                        break;
                    case 0x53: /* rbx */
                        value = memory.ReadLongInteger (rbp);
                        regs [(int) X86_Register.RBX].SetValue (rbp, value);
                        break;
                    case 0x56: /* rsi */
                        value = memory.ReadLongInteger (rbp);
                        regs [(int) X86_Register.RSI].SetValue (rbp, value);
                        break;
                    case 0x57: /* rdi */
                        value = memory.ReadLongInteger (rbp);
                        regs [(int) X86_Register.RDI].SetValue (rbp, value);
                        break;
                    }
                }

                rbp -= addr_size;
            }

            return CreateFrame (frame.Thread, FrameType.Normal, memory, new_rip, new_rsp, new_rbp, regs);
        }