summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Applications/CrashReporter/main.cpp12
-rw-r--r--Userland/Libraries/LibC/sys/arch/i386/regs.h21
-rw-r--r--Userland/Libraries/LibDebug/DebugInfo.cpp8
-rw-r--r--Userland/Libraries/LibDebug/DebugSession.cpp8
-rw-r--r--Userland/Libraries/LibDebug/DebugSession.h27
-rw-r--r--Userland/Utilities/strace.cpp12
6 files changed, 81 insertions, 7 deletions
diff --git a/Userland/Applications/CrashReporter/main.cpp b/Userland/Applications/CrashReporter/main.cpp
index b0f2b857c9..1a9dedff27 100644
--- a/Userland/Applications/CrashReporter/main.cpp
+++ b/Userland/Applications/CrashReporter/main.cpp
@@ -87,11 +87,23 @@ static TitleAndText build_cpu_registers(const ELF::Core::ThreadInfo& thread_info
StringBuilder builder;
+#if ARCH(I386)
builder.appendff("eax={:08x} ebx={:08x} ecx={:08x} edx={:08x}", regs.eax, regs.ebx, regs.ecx, regs.edx);
builder.append('\n');
builder.appendff("ebp={:08x} esp={:08x} esi={:08x} edi={:08x}", regs.ebp, regs.esp, regs.esi, regs.edi);
builder.append('\n');
builder.appendff("eip={:08x} eflags={:08x}", regs.eip, regs.eflags);
+#else
+ builder.appendff("rax={:16x} rbx={:16x} rcx={:16x} rdx={:16x}", regs.rax, regs.rbx, regs.rcx, regs.rdx);
+ builder.append('\n');
+ builder.appendff("rbp={:16x} rsp={:16x} rsi={:16x} rdi={:16x}", regs.rbp, regs.rsp, regs.rsi, regs.rdi);
+ builder.append('\n');
+ builder.appendff(" r8={:16x} r9={:16x} r10={:16x} r11={:16x}", regs.r8, regs.r9, regs.r10, regs.r11);
+ builder.append('\n');
+ builder.appendff("r12={:16x} r13={:16x} r14={:16x} r15={:16x}", regs.r12, regs.r13, regs.r14, regs.r15);
+ builder.append('\n');
+ builder.appendff("rip={:16x} rflags={:16x}", regs.rip, regs.rflags);
+#endif
return {
String::formatted("Thread #{} (TID {})", thread_index, thread_info.tid),
diff --git a/Userland/Libraries/LibC/sys/arch/i386/regs.h b/Userland/Libraries/LibC/sys/arch/i386/regs.h
index e2319c57b7..d276152579 100644
--- a/Userland/Libraries/LibC/sys/arch/i386/regs.h
+++ b/Userland/Libraries/LibC/sys/arch/i386/regs.h
@@ -9,6 +9,7 @@
#include <AK/Types.h>
struct [[gnu::packed]] PtraceRegisters {
+#if ARCH(I386)
u32 eax;
u32 ecx;
u32 edx;
@@ -19,6 +20,26 @@ struct [[gnu::packed]] PtraceRegisters {
u32 edi;
u32 eip;
u32 eflags;
+#else
+ u64 rax;
+ u64 rcx;
+ u64 rdx;
+ u64 rbx;
+ u64 rsp;
+ u64 rbp;
+ u64 rsi;
+ u64 rdi;
+ u64 rip;
+ u64 r8;
+ u64 r9;
+ u64 r10;
+ u64 r11;
+ u64 r12;
+ u64 r13;
+ u64 r14;
+ u64 r15;
+ u64 rflags;
+#endif
u32 cs;
u32 ss;
u32 ds;
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);
}
diff --git a/Userland/Utilities/strace.cpp b/Userland/Utilities/strace.cpp
index 12f6d32689..a8709e2bb5 100644
--- a/Userland/Utilities/strace.cpp
+++ b/Userland/Utilities/strace.cpp
@@ -128,10 +128,18 @@ int main(int argc, char** argv)
perror("getregs");
return 1;
}
+#if ARCH(I386)
u32 syscall_index = regs.eax;
u32 arg1 = regs.edx;
u32 arg2 = regs.ecx;
u32 arg3 = regs.ebx;
+#else
+ u64 syscall_index = regs.rax;
+ u64 arg1 = regs.rdx;
+ u64 arg2 = regs.rcx;
+ u64 arg3 = regs.rbx;
+#endif
+
if (ptrace(PT_SYSCALL, g_pid, 0, 0) == -1) {
perror("syscall");
@@ -147,7 +155,11 @@ int main(int argc, char** argv)
return 1;
}
+#if ARCH(I386)
u32 res = regs.eax;
+#else
+ u64 res = regs.rax;
+#endif
auto string = String::formatted("{}({:#08x}, {:#08x}, {:#08x})\t={}\n",
Syscall::to_string((Syscall::Function)syscall_index),