diff options
author | Gunnar Beutner <gbeutner@serenityos.org> | 2021-06-26 14:56:28 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-06-27 15:46:42 +0200 |
commit | 233ef26e4d67e6916de7829d880d78bbc2b6dd82 (patch) | |
tree | 6e1dc19888d510a53d3ec700bbbf56a54d27ef64 /Userland/Libraries/LibDebug | |
parent | 10ca7f18a7e46a67deb3d69db435ff127391f8ed (diff) | |
download | serenity-233ef26e4d67e6916de7829d880d78bbc2b6dd82.zip |
Kernel+Userland: Add x86_64 registers to RegisterState/PtraceRegisters
Diffstat (limited to 'Userland/Libraries/LibDebug')
-rw-r--r-- | Userland/Libraries/LibDebug/DebugInfo.cpp | 8 | ||||
-rw-r--r-- | Userland/Libraries/LibDebug/DebugSession.cpp | 8 | ||||
-rw-r--r-- | Userland/Libraries/LibDebug/DebugSession.h | 27 |
3 files changed, 36 insertions, 7 deletions
diff --git a/Userland/Libraries/LibDebug/DebugInfo.cpp b/Userland/Libraries/LibDebug/DebugInfo.cpp index 3e91bd1042..fb8398d5ff 100644 --- a/Userland/Libraries/LibDebug/DebugInfo.cpp +++ b/Userland/Libraries/LibDebug/DebugInfo.cpp @@ -167,7 +167,13 @@ NonnullOwnPtrVector<DebugInfo::VariableInfo> DebugInfo::get_variables_in_current // TODO: We can store the scopes in a better data structure for (const auto& scope : m_scopes) { - if (regs.eip - m_base_address < scope.address_low || regs.eip - m_base_address >= scope.address_high) + FlatPtr ip; +#if ARCH(I386) + ip = regs.eip; +#else + ip = regs.rip; +#endif + if (ip - m_base_address < scope.address_low || ip - m_base_address >= scope.address_high) continue; for (const auto& die_entry : scope.dies_of_variables) { diff --git a/Userland/Libraries/LibDebug/DebugSession.cpp b/Userland/Libraries/LibDebug/DebugSession.cpp index c874f5a12c..96aca1d894 100644 --- a/Userland/Libraries/LibDebug/DebugSession.cpp +++ b/Userland/Libraries/LibDebug/DebugSession.cpp @@ -324,7 +324,11 @@ void* DebugSession::single_step() auto regs = get_registers(); constexpr u32 TRAP_FLAG = 0x100; +#if ARCH(I386) regs.eflags |= TRAP_FLAG; +#else + regs.rflags |= TRAP_FLAG; +#endif set_registers(regs); continue_debuggee(); @@ -335,7 +339,11 @@ void* DebugSession::single_step() } regs = get_registers(); +#if ARCH(I386) regs.eflags &= ~(TRAP_FLAG); +#else + regs.rflags &= ~(TRAP_FLAG); +#endif set_registers(regs); #if ARCH(I386) return (void*)regs.eip; diff --git a/Userland/Libraries/LibDebug/DebugSession.h b/Userland/Libraries/LibDebug/DebugSession.h index f668b0f6d9..a81dd70e32 100644 --- a/Userland/Libraries/LibDebug/DebugSession.h +++ b/Userland/Libraries/LibDebug/DebugSession.h @@ -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); } |