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:
parent
10ca7f18a7
commit
233ef26e4d
13 changed files with 265 additions and 23 deletions
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue