diff options
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Applications/CrashReporter/main.cpp | 12 | ||||
-rw-r--r-- | Userland/Libraries/LibC/sys/arch/i386/regs.h | 21 | ||||
-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 | ||||
-rw-r--r-- | Userland/Utilities/strace.cpp | 12 |
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), |