mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 16:27:35 +00:00
Kernel+Userland: Add x86_64 registers to RegisterState/PtraceRegisters
This commit is contained in:
parent
10ca7f18a7
commit
233ef26e4d
13 changed files with 265 additions and 23 deletions
|
@ -15,6 +15,7 @@
|
|||
namespace Kernel {
|
||||
|
||||
struct [[gnu::packed]] RegisterState {
|
||||
#if ARCH(I386)
|
||||
FlatPtr ss;
|
||||
FlatPtr gs;
|
||||
FlatPtr fs;
|
||||
|
@ -28,27 +29,55 @@ struct [[gnu::packed]] RegisterState {
|
|||
FlatPtr edx;
|
||||
FlatPtr ecx;
|
||||
FlatPtr eax;
|
||||
#else
|
||||
FlatPtr rdi;
|
||||
FlatPtr rsi;
|
||||
FlatPtr rbp;
|
||||
FlatPtr rsp;
|
||||
FlatPtr rbx;
|
||||
FlatPtr rdx;
|
||||
FlatPtr rcx;
|
||||
FlatPtr rax;
|
||||
FlatPtr r8;
|
||||
FlatPtr r9;
|
||||
FlatPtr r10;
|
||||
FlatPtr r11;
|
||||
FlatPtr r12;
|
||||
FlatPtr r13;
|
||||
FlatPtr r14;
|
||||
FlatPtr r15;
|
||||
#endif
|
||||
u16 exception_code;
|
||||
u16 isr_number;
|
||||
#if ARCH(X86_64)
|
||||
u32 padding;
|
||||
#endif
|
||||
#if ARCH(I386)
|
||||
FlatPtr eip;
|
||||
#else
|
||||
FlatPtr rip;
|
||||
#endif
|
||||
FlatPtr cs;
|
||||
#if ARCH(I386)
|
||||
FlatPtr eflags;
|
||||
FlatPtr userspace_esp;
|
||||
FlatPtr userspace_ss;
|
||||
#else
|
||||
FlatPtr rflags;
|
||||
FlatPtr userspace_rsp;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if ARCH(I386)
|
||||
# define REGISTER_STATE_SIZE (19 * 4)
|
||||
#else
|
||||
# define REGISTER_STATE_SIZE (19 * 8)
|
||||
# define REGISTER_STATE_SIZE (21 * 8)
|
||||
#endif
|
||||
static_assert(REGISTER_STATE_SIZE == sizeof(RegisterState));
|
||||
|
||||
inline void copy_kernel_registers_into_ptrace_registers(PtraceRegisters& ptrace_regs, const RegisterState& kernel_regs)
|
||||
{
|
||||
#if ARCH(I386)
|
||||
ptrace_regs.eax = kernel_regs.eax,
|
||||
ptrace_regs.ecx = kernel_regs.ecx,
|
||||
ptrace_regs.edx = kernel_regs.edx,
|
||||
|
@ -59,6 +88,26 @@ inline void copy_kernel_registers_into_ptrace_registers(PtraceRegisters& ptrace_
|
|||
ptrace_regs.edi = kernel_regs.edi,
|
||||
ptrace_regs.eip = kernel_regs.eip,
|
||||
ptrace_regs.eflags = kernel_regs.eflags,
|
||||
#else
|
||||
ptrace_regs.rax = kernel_regs.rax,
|
||||
ptrace_regs.rcx = kernel_regs.rcx,
|
||||
ptrace_regs.rdx = kernel_regs.rdx,
|
||||
ptrace_regs.rbx = kernel_regs.rbx,
|
||||
ptrace_regs.rsp = kernel_regs.userspace_rsp,
|
||||
ptrace_regs.rbp = kernel_regs.rbp,
|
||||
ptrace_regs.rsi = kernel_regs.rsi,
|
||||
ptrace_regs.rdi = kernel_regs.rdi,
|
||||
ptrace_regs.rip = kernel_regs.rip,
|
||||
ptrace_regs.r8 = kernel_regs.r8;
|
||||
ptrace_regs.r9 = kernel_regs.r9;
|
||||
ptrace_regs.r10 = kernel_regs.r10;
|
||||
ptrace_regs.r11 = kernel_regs.r11;
|
||||
ptrace_regs.r12 = kernel_regs.r12;
|
||||
ptrace_regs.r13 = kernel_regs.r13;
|
||||
ptrace_regs.r14 = kernel_regs.r14;
|
||||
ptrace_regs.r15 = kernel_regs.r15;
|
||||
ptrace_regs.rflags = kernel_regs.rflags,
|
||||
#endif
|
||||
ptrace_regs.cs = 0;
|
||||
ptrace_regs.ss = 0;
|
||||
ptrace_regs.ds = 0;
|
||||
|
@ -69,6 +118,7 @@ inline void copy_kernel_registers_into_ptrace_registers(PtraceRegisters& ptrace_
|
|||
|
||||
inline void copy_ptrace_registers_into_kernel_registers(RegisterState& kernel_regs, const PtraceRegisters& ptrace_regs)
|
||||
{
|
||||
#if ARCH(I386)
|
||||
kernel_regs.eax = ptrace_regs.eax;
|
||||
kernel_regs.ecx = ptrace_regs.ecx;
|
||||
kernel_regs.edx = ptrace_regs.edx;
|
||||
|
@ -79,6 +129,27 @@ inline void copy_ptrace_registers_into_kernel_registers(RegisterState& kernel_re
|
|||
kernel_regs.edi = ptrace_regs.edi;
|
||||
kernel_regs.eip = ptrace_regs.eip;
|
||||
kernel_regs.eflags = (kernel_regs.eflags & ~safe_eflags_mask) | (ptrace_regs.eflags & safe_eflags_mask);
|
||||
#else
|
||||
kernel_regs.rax = ptrace_regs.rax;
|
||||
kernel_regs.rcx = ptrace_regs.rcx;
|
||||
kernel_regs.rdx = ptrace_regs.rdx;
|
||||
kernel_regs.rbx = ptrace_regs.rbx;
|
||||
kernel_regs.rsp = ptrace_regs.rsp;
|
||||
kernel_regs.rbp = ptrace_regs.rbp;
|
||||
kernel_regs.rsi = ptrace_regs.rsi;
|
||||
kernel_regs.rdi = ptrace_regs.rdi;
|
||||
kernel_regs.rip = ptrace_regs.rip;
|
||||
kernel_regs.r8 = ptrace_regs.r8;
|
||||
kernel_regs.r9 = ptrace_regs.r9;
|
||||
kernel_regs.r10 = ptrace_regs.r10;
|
||||
kernel_regs.r11 = ptrace_regs.r11;
|
||||
kernel_regs.r12 = ptrace_regs.r12;
|
||||
kernel_regs.r13 = ptrace_regs.r13;
|
||||
kernel_regs.r14 = ptrace_regs.r14;
|
||||
kernel_regs.r15 = ptrace_regs.r15;
|
||||
// FIXME: do we need a separate safe_rflags_mask here?
|
||||
kernel_regs.rflags = (kernel_regs.rflags & ~safe_eflags_mask) | (ptrace_regs.rflags & safe_eflags_mask);
|
||||
#endif
|
||||
}
|
||||
|
||||
struct [[gnu::packed]] DebugRegisterState {
|
||||
|
|
|
@ -117,6 +117,7 @@ asm( \
|
|||
|
||||
static void dump(const RegisterState& regs)
|
||||
{
|
||||
#if ARCH(I386)
|
||||
u16 ss;
|
||||
u32 esp;
|
||||
|
||||
|
@ -127,14 +128,33 @@ static void dump(const RegisterState& regs)
|
|||
ss = regs.userspace_ss;
|
||||
esp = regs.userspace_esp;
|
||||
}
|
||||
#else
|
||||
u64 rsp;
|
||||
|
||||
if (!(regs.cs & 3))
|
||||
rsp = regs.rsp;
|
||||
else
|
||||
rsp = regs.userspace_rsp;
|
||||
#endif
|
||||
|
||||
dbgln("Exception code: {:04x} (isr: {:04x})", regs.exception_code, regs.isr_number);
|
||||
#if ARCH(I386)
|
||||
dbgln(" pc={:04x}:{:08x} eflags={:08x}", (u16)regs.cs, regs.eip, regs.eflags);
|
||||
dbgln(" stack={:04x}:{:08x}", ss, esp);
|
||||
dbgln(" ds={:04x} es={:04x} fs={:04x} gs={:04x}", (u16)regs.ds, (u16)regs.es, (u16)regs.fs, (u16)regs.gs);
|
||||
dbgln(" eax={:08x} ebx={:08x} ecx={:08x} edx={:08x}", regs.eax, regs.ebx, regs.ecx, regs.edx);
|
||||
dbgln(" ebp={:08x} esp={:08x} esi={:08x} edi={:08x}", regs.ebp, regs.esp, regs.esi, regs.edi);
|
||||
dbgln(" cr0={:08x} cr2={:08x} cr3={:08x} cr4={:08x}", read_cr0(), read_cr2(), read_cr3(), read_cr4());
|
||||
#else
|
||||
dbgln(" pc={:04x}:{:16x} rflags={:16x}", (u16)regs.cs, regs.rip, regs.rflags);
|
||||
dbgln(" stack={:16x}", rsp);
|
||||
// FIXME: Add fs_base and gs_base here
|
||||
dbgln(" rax={:16x} rbx={:16x} rcx={:16x} rdx={:16x}", regs.rax, regs.rbx, regs.rcx, regs.rdx);
|
||||
dbgln(" rbp={:16x} rsp={:16x} rsi={:16x} rdi={:16x}", regs.rbp, regs.rsp, regs.rsi, regs.rdi);
|
||||
dbgln(" r8={:16x} r9={:16x} r10={:16x} r11={:16x}", regs.r8, regs.r9, regs.r10, regs.r11);
|
||||
dbgln(" r12={:16x} r13={:16x} r14={:16x} r15={:16x}", regs.r12, regs.r13, regs.r14, regs.r15);
|
||||
dbgln(" cr0={:16x} cr2={:16x} cr3={:16x} cr4={:16x}", read_cr0(), read_cr2(), read_cr3(), read_cr4());
|
||||
#endif
|
||||
}
|
||||
|
||||
void handle_crash(RegisterState& regs, const char* description, int signal, bool out_of_memory)
|
||||
|
@ -155,7 +175,13 @@ void handle_crash(RegisterState& regs, const char* description, int signal, bool
|
|||
PANIC("Crash in ring 0");
|
||||
}
|
||||
|
||||
process->crash(signal, regs.eip, out_of_memory);
|
||||
FlatPtr ip;
|
||||
#if ARCH(I386)
|
||||
ip = regs.eip;
|
||||
#else
|
||||
ip = regs.rip;
|
||||
#endif
|
||||
process->crash(signal, ip, out_of_memory);
|
||||
}
|
||||
|
||||
EH_ENTRY_NO_CODE(6, illegal_instruction);
|
||||
|
@ -237,8 +263,14 @@ void page_fault_handler(TrapFrame* trap)
|
|||
current_thread->set_handling_page_fault(false);
|
||||
};
|
||||
|
||||
if (!faulted_in_kernel && !MM.validate_user_stack(current_thread->process(), VirtualAddress(regs.userspace_esp))) {
|
||||
dbgln("Invalid stack pointer: {}", VirtualAddress(regs.userspace_esp));
|
||||
VirtualAddress userspace_sp;
|
||||
#if ARCH(I386)
|
||||
userspace_sp = VirtualAddress { regs.userspace_esp };
|
||||
#else
|
||||
userspace_sp = VirtualAddress { regs.userspace_rsp };
|
||||
#endif
|
||||
if (!faulted_in_kernel && !MM.validate_user_stack(current_thread->process(), userspace_sp)) {
|
||||
dbgln("Invalid stack pointer: {}", userspace_sp);
|
||||
handle_crash(regs, "Bad stack on page fault", SIGSTKFLT);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue