/* * Copyright (c) 2018-2021, James Mintram * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include VALIDATE_IS_AARCH64() namespace Kernel { struct RegisterState { u64 x[31]; // Saved general purpose registers u64 spsr_el1; // Save Processor Status Register, EL1 u64 elr_el1; // Exception Link Register, EL1 u64 sp_el0; // EL0 stack pointer FlatPtr userspace_sp() const { return sp_el0; } void set_userspace_sp(FlatPtr value) { sp_el0 = value; } FlatPtr ip() const { return elr_el1; } void set_ip(FlatPtr value) { elr_el1 = value; } FlatPtr bp() const { return x[29]; } ExecutionMode previous_mode() const { return ((spsr_el1 & 0b1111) == 0) ? ExecutionMode::User : ExecutionMode::Kernel; } void set_return_reg(FlatPtr value) { x[0] = value; } void capture_syscall_params(FlatPtr& function, FlatPtr& arg1, FlatPtr& arg2, FlatPtr& arg3, FlatPtr& arg4) const { function = x[8]; arg1 = x[1]; arg2 = x[2]; arg3 = x[3]; arg4 = x[4]; } }; #define REGISTER_STATE_SIZE (34 * 8) static_assert(AssertSize()); inline void copy_kernel_registers_into_ptrace_registers(PtraceRegisters& ptrace_regs, RegisterState const& kernel_regs) { for (auto i = 0; i < 31; i++) ptrace_regs.x[i] = kernel_regs.x[i]; ptrace_regs.sp = kernel_regs.userspace_sp(); ptrace_regs.pc = kernel_regs.ip(); } inline void copy_ptrace_registers_into_kernel_registers(RegisterState& kernel_regs, PtraceRegisters const& ptrace_regs) { for (auto i = 0; i < 31; i++) kernel_regs.x[i] = ptrace_regs.x[i]; kernel_regs.set_userspace_sp(ptrace_regs.sp); kernel_regs.set_ip(ptrace_regs.pc); } struct DebugRegisterState { }; }