summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibDebug
diff options
context:
space:
mode:
authorGunnar Beutner <gbeutner@serenityos.org>2021-06-26 14:56:28 +0200
committerAndreas Kling <kling@serenityos.org>2021-06-27 15:46:42 +0200
commit233ef26e4d67e6916de7829d880d78bbc2b6dd82 (patch)
tree6e1dc19888d510a53d3ec700bbbf56a54d27ef64 /Userland/Libraries/LibDebug
parent10ca7f18a7e46a67deb3d69db435ff127391f8ed (diff)
downloadserenity-233ef26e4d67e6916de7829d880d78bbc2b6dd82.zip
Kernel+Userland: Add x86_64 registers to RegisterState/PtraceRegisters
Diffstat (limited to 'Userland/Libraries/LibDebug')
-rw-r--r--Userland/Libraries/LibDebug/DebugInfo.cpp8
-rw-r--r--Userland/Libraries/LibDebug/DebugSession.cpp8
-rw-r--r--Userland/Libraries/LibDebug/DebugSession.h27
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);
}