1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 04:07:45 +00:00

Kernel+Userland: Add x86_64 registers to RegisterState/PtraceRegisters

This commit is contained in:
Gunnar Beutner 2021-06-26 14:56:28 +02:00 committed by Andreas Kling
parent 10ca7f18a7
commit 233ef26e4d
13 changed files with 265 additions and 23 deletions

View file

@ -218,6 +218,12 @@ void DebugSession::run(DesiredInitialDebugeeState initial_debugee_state, Callbac
auto regs = get_registers();
#if ARCH(I386)
FlatPtr current_instruction = regs.eip;
#else
FlatPtr current_instruction = regs.rip;
#endif
auto debug_status = peek_debug(DEBUG_STATUS_REGISTER);
if (debug_status.has_value() && (debug_status.value() & 0b1111) > 0) {
// Tripped a watchpoint
@ -233,8 +239,12 @@ void DebugSession::run(DesiredInitialDebugeeState initial_debugee_state, Callbac
auto required_ebp = watchpoint.value().ebp;
auto found_ebp = false;
u32 current_ebp = regs.ebp;
u32 current_instruction = regs.eip;
#if ARCH(I386)
FlatPtr current_ebp = regs.ebp;
#else
FlatPtr current_ebp = regs.rbp;
#endif
do {
if (current_ebp == required_ebp) {
found_ebp = true;
@ -259,22 +269,27 @@ void DebugSession::run(DesiredInitialDebugeeState initial_debugee_state, Callbac
Optional<BreakPoint> current_breakpoint;
if (state == State::FreeRun || state == State::Syscall) {
current_breakpoint = m_breakpoints.get((void*)((uintptr_t)regs.eip - 1));
current_breakpoint = m_breakpoints.get((void*)((uintptr_t)current_instruction - 1));
if (current_breakpoint.has_value())
state = State::FreeRun;
} else {
current_breakpoint = m_breakpoints.get((void*)regs.eip);
current_breakpoint = m_breakpoints.get((void*)current_instruction);
}
if (current_breakpoint.has_value()) {
// We want to make the breakpoint transparent to the user of the debugger.
// To achieive this, we perform two rollbacks:
// To achieve this, we perform two rollbacks:
// 1. Set regs.eip to point at the actual address of the instruction we breaked on.
// regs.eip currently points to one byte after the address of the original instruction,
// because the cpu has just executed the INT3 we patched into the instruction.
// 2. We restore the original first byte of the instruction,
// because it was patched with INT3.
regs.eip = reinterpret_cast<u32>(current_breakpoint.value().address);
auto breakpoint_addr = reinterpret_cast<uintptr_t>(current_breakpoint.value().address);
#if ARCH(I386)
regs.eip = breakpoint_addr;
#else
regs.rip = breakpoint_addr;
#endif
set_registers(regs);
disable_breakpoint(current_breakpoint.value().address);
}