[haiku-commits] BRANCH xyzzy-github.x86_64 - in src/system/kernel/arch/x86: . 64

  • From: xyzzy-github.x86_64 <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 13 Jul 2012 15:49:07 +0200 (CEST)

added 1 changeset to branch 'refs/remotes/xyzzy-github/x86_64'
old head: e690e5ab3b4adc583b94a27400b7fd12da80ce51
new head: bcb07a319b647eb0af60398e972525cc0a686aa9

----------------------------------------------------------------------------

bcb07a3: Implemented the rest of the kernel debugger functions for x86_64.
  
  Merged with the x86 implementations, mostly the same except for a
  few differences. GDB stub is currently broken, will investigate
  later.

                                      [ Alex Smith <alex@xxxxxxxxxxxxxxxx> ]

----------------------------------------------------------------------------

Commit:      bcb07a319b647eb0af60398e972525cc0a686aa9

Author:      Alex Smith <alex@xxxxxxxxxxxxxxxx>
Date:        Fri Jul 13 13:09:09 2012 UTC

----------------------------------------------------------------------------

6 files changed, 335 insertions(+), 423 deletions(-)
headers/private/kernel/arch/x86/64/iframe.h        |   13 +-
.../private/kernel/arch/x86/arch_thread_types.h    |   26 +-
src/system/kernel/arch/x86/64/stubs.cpp            |  209 -------
src/system/kernel/arch/x86/Jamfile                 |    2 +-
src/system/kernel/arch/x86/arch_debug.cpp          |  496 +++++++++-------
src/system/kernel/arch/x86/arch_thread.cpp         |   12 +-

----------------------------------------------------------------------------

diff --git a/headers/private/kernel/arch/x86/64/iframe.h 
b/headers/private/kernel/arch/x86/64/iframe.h
index cd257ef..ff0dae7 100644
--- a/headers/private/kernel/arch/x86/64/iframe.h
+++ b/headers/private/kernel/arch/x86/64/iframe.h
@@ -29,9 +29,16 @@ struct iframe {
        uint64 cs;
        uint64 flags;
 
-       // Only present when the iframe is a userland iframe (IFRAME_IS_USER()).
-       uint64 user_sp;
-       uint64 user_ss;
+       // SP and SS are unconditionally present on x86_64, make both names
+       // available.
+       union {
+               uint64 sp;
+               uint64 user_sp;
+       };
+       union {
+               uint64 ss;
+               uint64 user_ss;
+       };
 } _PACKED;
 
 #define IFRAME_IS_USER(f)      (((f)->cs & DPL_USER) == DPL_USER)
diff --git a/headers/private/kernel/arch/x86/arch_thread_types.h 
b/headers/private/kernel/arch/x86/arch_thread_types.h
index 209543e..85dfc6b 100644
--- a/headers/private/kernel/arch/x86/arch_thread_types.h
+++ b/headers/private/kernel/arch/x86/arch_thread_types.h
@@ -48,6 +48,8 @@ struct arch_thread {
 
        // 512 byte floating point save point - this must be 16 byte aligned
        uint8                   fpu_state[512] _ALIGNED(16);
+
+       addr_t                  GetFramePointer() const;
 } _ALIGNED(16);
 
 
@@ -64,4 +66,26 @@ struct arch_fork_arg {
 };
 
 
-#endif /* _KERNEL_ARCH_x86_THREAD_TYPES_H */
+#ifdef __x86_64__
+
+
+inline addr_t
+arch_thread::GetFramePointer() const
+{
+       return current_stack[1];
+}
+
+
+#else
+
+
+inline addr_t
+arch_thread::GetFramePointer() const
+{
+       return current_stack.esp[2];
+}
+
+
+#endif // __x86_64__
+
+#endif // _KERNEL_ARCH_x86_THREAD_TYPES_H
diff --git a/src/system/kernel/arch/x86/64/stubs.cpp 
b/src/system/kernel/arch/x86/64/stubs.cpp
index 72b95c6..b8efb2f 100644
--- a/src/system/kernel/arch/x86/64/stubs.cpp
+++ b/src/system/kernel/arch/x86/64/stubs.cpp
@@ -52,215 +52,6 @@ arch_commpage_init_post_cpus(void)
 
 
 void
-arch_debug_save_registers(struct arch_debug_registers* registers)
-{
-
-}
-
-
-struct stack_frame {
-       struct stack_frame      *previous;
-       addr_t                          return_address;
-};
-
-
-static bool
-is_iframe(addr_t frame)
-{
-       addr_t previousFrame = *(addr_t*)frame;
-       return ((previousFrame & ~(addr_t)IFRAME_TYPE_MASK) == 0
-               && previousFrame != 0);
-}
-
-
-static void
-print_iframe(struct iframe* frame)
-{
-       bool isUser = IFRAME_IS_USER(frame);
-
-       kprintf("%s iframe at %p (end = %p)\n", isUser ? "user" : "kernel", 
frame,
-               isUser ? (uint64*)(frame + 1) : &frame->user_sp);
-
-       kprintf(" rax 0x%-16lx    rbx 0x%-16lx    rcx 0x%lx\n", frame->ax,
-               frame->bx, frame->cx);
-       kprintf(" rdx 0x%-16lx    rsi 0x%-16lx    rdi 0x%lx\n", frame->dx,
-               frame->si, frame->di);
-       kprintf(" rbp 0x%-16lx     r8 0x%-16lx     r9 0x%lx\n", frame->bp,
-               frame->r8, frame->r9);
-       kprintf(" r10 0x%-16lx    r11 0x%-16lx    r12 0x%lx\n", frame->r10,
-               frame->r11, frame->r12);
-       kprintf(" r13 0x%-16lx    r14 0x%-16lx    r15 0x%lx\n", frame->r13,
-               frame->r14, frame->r15);
-       kprintf(" rip 0x%-16lx rflags 0x%-16lx", frame->ip, frame->flags);
-
-       if (isUser) {
-               // from user space
-               kprintf("user rsp 0x%lx", frame->user_sp);
-       }
-       kprintf("\n");
-       kprintf(" vector: 0x%lx, error code: 0x%lx\n", frame->vector,
-               frame->error_code);
-}
-
-
-static status_t
-lookup_symbol(addr_t address, addr_t* _baseAddress, const char** _symbolName,
-       const char** _imageName, bool* _exactMatch)
-{
-       status_t status = B_ENTRY_NOT_FOUND;
-
-       if (IS_KERNEL_ADDRESS(address)) {
-               status = elf_debug_lookup_symbol_address(address, _baseAddress,
-                       _symbolName, _imageName, _exactMatch);
-       }
-
-       return status;
-}
-
-
-static void
-print_stack_frame(addr_t rip, addr_t rbp, addr_t nextRbp, int32 callIndex)
-{
-       const char* symbol;
-       const char* image;
-       addr_t baseAddress;
-       bool exactMatch;
-       status_t status;
-       addr_t diff;
-
-       diff = nextRbp - rbp;
-
-       // kernel space/user space switch
-       if (diff & (1L << 63))
-               diff = 0;
-
-       status = lookup_symbol(rip, &baseAddress, &symbol, &image, &exactMatch);
-
-       kprintf("%2d %016lx (+%4ld) %016lx   ", callIndex, rbp, diff, rip);
-
-       if (status == B_OK) {
-               if (symbol != NULL)
-                       kprintf("<%s>:%s%s", image, symbol, exactMatch ? "" : " 
(nearest)");
-               else
-                       kprintf("<%s@%p>:unknown", image, (void*)baseAddress);
-
-               kprintf(" + 0x%04lx\n", rip - baseAddress);
-       } else {
-               VMArea *area = VMAddressSpace::Kernel()->LookupArea(rip);
-               if (area != NULL) {
-                       kprintf("%d:%s@%p + %#lx\n", area->id, area->name,
-                               (void*)area->Base(), rip - area->Base());
-               } else
-                       kprintf("\n");
-       }
-}
-
-
-void
-arch_debug_stack_trace(void)
-{
-       addr_t rbp = x86_get_stack_frame();
-
-       kprintf("frame                       caller             
<image>:function"
-               " + offset\n");
-
-       for (int32 callIndex = 0;; callIndex++) {
-               if (rbp == 0)
-                       break;
-
-               if (is_iframe(rbp)) {
-                       struct iframe* frame = (struct iframe*)rbp;
-                       print_iframe(frame);
-                       print_stack_frame(frame->ip, rbp, frame->bp, callIndex);
-
-                       rbp = frame->bp;
-               } else {
-                       stack_frame* frame = (stack_frame*)rbp;
-                       if (frame->return_address == 0)
-                               break;
-
-                       print_stack_frame(frame->return_address, rbp,
-                               (frame->previous != NULL) ? 
(addr_t)frame->previous : rbp,
-                               callIndex);
-
-                       rbp = (addr_t)frame->previous;
-               }
-       }
-}
-
-
-bool
-arch_debug_contains_call(Thread *thread, const char *symbol,
-       addr_t start, addr_t end)
-{
-       return false;
-}
-
-
-void *
-arch_debug_get_caller(void)
-{
-       return NULL;
-}
-
-
-int32
-arch_debug_get_stack_trace(addr_t* returnAddresses, int32 maxCount,
-       int32 skipIframes, int32 skipFrames, uint32 flags)
-{
-       return 0;
-}
-
-
-void*
-arch_debug_get_interrupt_pc(bool* _isSyscall)
-{
-       return NULL;
-}
-
-
-void
-arch_debug_unset_current_thread(void)
-{
-
-}
-
-
-bool
-arch_is_debug_variable_defined(const char* variableName)
-{
-       return false;
-}
-
-
-status_t
-arch_set_debug_variable(const char* variableName, uint64 value)
-{
-       return B_OK;
-}
-
-
-status_t
-arch_get_debug_variable(const char* variableName, uint64* value)
-{
-       return B_OK;
-}
-
-
-ssize_t
-arch_debug_gdb_get_registers(char* buffer, size_t bufferSize)
-{
-       return B_ERROR;
-}
-
-
-status_t
-arch_debug_init(kernel_args *args)
-{
-       return B_OK;
-}
-
-void
 arch_debug_call_with_fault_handler(cpu_ent* cpu, jmp_buf jumpBuffer,
        void (*function)(void*), void* parameter)
 {
diff --git a/src/system/kernel/arch/x86/Jamfile 
b/src/system/kernel/arch/x86/Jamfile
index 2d41509..9b1a888 100644
--- a/src/system/kernel/arch/x86/Jamfile
+++ b/src/system/kernel/arch/x86/Jamfile
@@ -51,7 +51,6 @@ if $(TARGET_ARCH) = x86_64 {
                vm86.cpp
 
                arch_commpage.cpp
-               arch_debug.cpp
                arch_user_debugger.cpp
                ioapic.cpp
                irq_routing_table.cpp
@@ -78,6 +77,7 @@ if $(TARGET_ARCH) = x86_64 {
 
 local archGenericSources =
        arch_cpu.cpp
+       arch_debug.cpp
        arch_debug_console.cpp
        arch_elf.cpp
        arch_int.cpp
diff --git a/src/system/kernel/arch/x86/arch_debug.cpp 
b/src/system/kernel/arch/x86/arch_debug.cpp
index 9d21c7b..0f3faa8 100644
--- a/src/system/kernel/arch/x86/arch_debug.cpp
+++ b/src/system/kernel/arch/x86/arch_debug.cpp
@@ -1,6 +1,7 @@
 /*
  * Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@xxxxxxx
  * Copyright 2002-2008, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
+ * Copyright 2012, Alex Smith, alex@xxxxxxxxxxxxxxxxx
  * Distributed under the terms of the MIT License.
  *
  * Copyright 2001, Travis Geiselbrecht. All rights reserved.
@@ -28,31 +29,29 @@
 #include <vm/VMAddressSpace.h>
 #include <vm/VMArea.h>
 
-#include <arch_cpu.h>
-
 
 struct stack_frame {
-       struct stack_frame      *previous;
-       addr_t                          return_address;
+       stack_frame*    previous;
+       addr_t                  return_address;
 };
 
 #define NUM_PREVIOUS_LOCATIONS 32
 
 
 static bool
-already_visited(uint32 *visited, int32 *_last, int32 *_num, uint32 ebp)
+already_visited(addr_t* visited, int32* _last, int32* _num, addr_t bp)
 {
        int32 last = *_last;
        int32 num = *_num;
        int32 i;
 
        for (i = 0; i < num; i++) {
-               if (visited[(NUM_PREVIOUS_LOCATIONS + last - i) % 
NUM_PREVIOUS_LOCATIONS] == ebp)
+               if (visited[(NUM_PREVIOUS_LOCATIONS + last - i) % 
NUM_PREVIOUS_LOCATIONS] == bp)
                        return true;
        }
 
        *_last = last = (last + 1) % NUM_PREVIOUS_LOCATIONS;
-       visited[last] = ebp;
+       visited[last] = bp;
 
        if (num < NUM_PREVIOUS_LOCATIONS)
                *_num = num + 1;
@@ -64,14 +63,14 @@ already_visited(uint32 *visited, int32 *_last, int32 *_num, 
uint32 ebp)
 /*!    Safe to be called only from outside the debugger.
 */
 static status_t
-get_next_frame_no_debugger(addr_t ebp, addr_t *_next, addr_t *_eip)
+get_next_frame_no_debugger(addr_t bp, addr_t* _next, addr_t* _ip)
 {
        // TODO: Do this more efficiently in assembly.
        stack_frame frame;
-       if (user_memcpy(&frame, (void*)ebp, sizeof(frame)) != B_OK)
+       if (user_memcpy(&frame, (void*)bp, sizeof(frame)) != B_OK)
                return B_BAD_ADDRESS;
 
-       *_eip = frame.return_address;
+       *_ip = frame.return_address;
        *_next = (addr_t)frame.previous;
 
        return B_OK;
@@ -81,13 +80,13 @@ get_next_frame_no_debugger(addr_t ebp, addr_t *_next, 
addr_t *_eip)
 /*!    Safe to be called only from inside the debugger.
 */
 static status_t
-get_next_frame_debugger(addr_t ebp, addr_t *_next, addr_t *_eip)
+get_next_frame_debugger(addr_t bp, addr_t* _next, addr_t* _ip)
 {
        stack_frame frame;
-       if (debug_memcpy(B_CURRENT_TEAM, &frame, (void*)ebp, sizeof(frame)) != 
B_OK)
+       if (debug_memcpy(B_CURRENT_TEAM, &frame, (void*)bp, sizeof(frame)) != 
B_OK)
                return B_BAD_ADDRESS;
 
-       *_eip = frame.return_address;
+       *_ip = frame.return_address;
        *_next = (addr_t)frame.previous;
 
        return B_OK;
@@ -95,8 +94,8 @@ get_next_frame_debugger(addr_t ebp, addr_t *_next, addr_t 
*_eip)
 
 
 static status_t
-lookup_symbol(Thread* thread, addr_t address, addr_t *_baseAddress,
-       const char **_symbolName, const char **_imageName, bool *_exactMatch)
+lookup_symbol(Thread* thread, addr_t address, addr_t* _baseAddress,
+       const char** _symbolName, const char** _imageName, bool* _exactMatch)
 {
        status_t status = B_ENTRY_NOT_FOUND;
 
@@ -120,6 +119,9 @@ lookup_symbol(Thread* thread, addr_t address, addr_t 
*_baseAddress,
 }
 
 
+#ifndef __x86_64__
+
+
 static void
 set_debug_argument_variable(int32 index, uint64 value)
 {
@@ -307,31 +309,53 @@ print_demangled_call(const char* image, const char* 
symbol, addr_t args,
 }
 
 
+#else  // __x86_64__
+
+
+static status_t
+print_demangled_call(const char* image, const char* symbol, addr_t args,
+       bool noObjectMethod, bool addDebugVariables)
+{
+       // Since x86_64 uses registers rather than the stack for the first 6
+       // arguments we cannot use the same method as x86 to read the function
+       // arguments. Maybe we need DWARF support in the kernel debugger. For 
now
+       // just print out the function signature without the argument values.
+
+       // TODO x86_64.
+       return B_NOT_SUPPORTED;
+}
+
+
+#endif // __x86_64__
+
+
 static void
-print_stack_frame(Thread *thread, addr_t eip, addr_t ebp, addr_t nextEbp,
+print_stack_frame(Thread* thread, addr_t ip, addr_t bp, addr_t nextBp,
        int32 callIndex, bool demangle)
 {
-       const char *symbol, *image;
+       const char* symbol;
+       const char* image;
        addr_t baseAddress;
        bool exactMatch;
        status_t status;
        addr_t diff;
 
-       diff = nextEbp - ebp;
+       diff = nextBp - bp;
 
-       // kernel space/user space switch
-       if (diff & 0x80000000)
+       // MSB set = kernel space/user space switch
+       if (diff & ~((addr_t)-1 >> 1))
                diff = 0;
 
-       status = lookup_symbol(thread, eip, &baseAddress, &symbol, &image,
+       status = lookup_symbol(thread, ip, &baseAddress, &symbol, &image,
                &exactMatch);
 
-       kprintf("%2ld %08lx (+%4ld) %08lx   ", callIndex, ebp, diff, eip);
+       kprintf("%2" B_PRId32 " %0*lx (+%4ld) %0*lx   ", callIndex,
+               B_PRINTF_POINTER_WIDTH, bp, diff, B_PRINTF_POINTER_WIDTH, ip);
 
        if (status == B_OK) {
                if (exactMatch && demangle) {
-                       status = print_demangled_call(image, symbol, nextEbp + 
8, false,
-                               false);
+                       status = print_demangled_call(image, symbol,
+                               nextBp + sizeof(stack_frame), false, false);
                }
 
                if (!exactMatch || !demangle || status != B_OK) {
@@ -339,19 +363,19 @@ print_stack_frame(Thread *thread, addr_t eip, addr_t ebp, 
addr_t nextEbp,
                                kprintf("<%s>:%s%s", image, symbol,
                                        exactMatch ? "" : " (nearest)");
                        } else
-                               kprintf("<%s@%p>:unknown", image, (void 
*)baseAddress);
+                               kprintf("<%s@%p>:unknown", image, 
(void*)baseAddress);
                }
 
-               kprintf(" + 0x%04lx\n", eip - baseAddress);
+               kprintf(" + %#04lx\n", ip - baseAddress);
        } else {
                VMArea *area = NULL;
                if (thread != NULL && thread->team != NULL
                        && thread->team->address_space != NULL) {
-                       area = thread->team->address_space->LookupArea(eip);
+                       area = thread->team->address_space->LookupArea(ip);
                }
                if (area != NULL) {
-                       kprintf("%ld:%s@%p + %#lx\n", area->id, area->name,
-                               (void*)area->Base(), eip - area->Base());
+                       kprintf("%" B_PRId32 ":%s@%p + %#lx\n", area->id, 
area->name,
+                               (void*)area->Base(), ip - area->Base());
                } else
                        kprintf("\n");
        }
@@ -359,45 +383,65 @@ print_stack_frame(Thread *thread, addr_t eip, addr_t ebp, 
addr_t nextEbp,
 
 
 static void
-print_iframe(struct iframe *frame)
+print_iframe(iframe* frame)
 {
        bool isUser = IFRAME_IS_USER(frame);
+
+#ifdef __x86_64__
+       kprintf("%s iframe at %p (end = %p)\n", isUser ? "user" : "kernel", 
frame,
+               frame + 1);
+
+       kprintf(" rax %#-18lx    rbx %#-18lx    rcx %#lx\n", frame->ax,
+               frame->bx, frame->cx);
+       kprintf(" rdx %#-18lx    rsi %#-18lx    rdi %#lx\n", frame->dx,
+               frame->si, frame->di);
+       kprintf(" rbp %#-18lx     r8 %#-18lx     r9 %#lx\n", frame->bp,
+               frame->r8, frame->r9);
+       kprintf(" r10 %#-18lx    r11 %#-18lx    r12 %#lx\n", frame->r10,
+               frame->r11, frame->r12);
+       kprintf(" r13 %#-18lx    r14 %#-18lx    r15 %#lx\n", frame->r13,
+               frame->r14, frame->r15);
+       kprintf(" rip %#-18lx    rsp %#-18lx rflags %#lx\n", frame->ip,
+               frame->sp, frame->flags);
+#else
        kprintf("%s iframe at %p (end = %p)\n", isUser ? "user" : "kernel", 
frame,
-               isUser ? (uint32*)(frame + 1) : &frame->user_sp);
+               isUser ? (void*)(frame + 1) : (void*)&frame->user_sp);
 
-       kprintf(" eax 0x%-9lx    ebx 0x%-9lx     ecx 0x%-9lx  edx 0x%lx\n",
+       kprintf(" eax %#-10lx    ebx %#-10lx     ecx %#-10lx  edx %#lx\n",
                frame->ax, frame->bx, frame->cx, frame->dx);
-       kprintf(" esi 0x%-9lx    edi 0x%-9lx     ebp 0x%-9lx  esp 0x%lx\n",
+       kprintf(" esi %#-10lx    edi %#-10lx     ebp %#-10lx  esp %#lx\n",
                frame->si, frame->di, frame->bp, frame->sp);
-       kprintf(" eip 0x%-9lx eflags 0x%-9lx", frame->ip, frame->flags);
+       kprintf(" eip %#-10lx eflags %#-10lx", frame->ip, frame->flags);
        if (isUser) {
                // from user space
-               kprintf("user esp 0x%lx", frame->user_sp);
+               kprintf("user esp %#lx", frame->user_sp);
        }
        kprintf("\n");
-       kprintf(" vector: 0x%lx, error code: 0x%lx\n", frame->vector,
+#endif
+
+       kprintf(" vector: %#lx, error code: %#lx\n", frame->vector,
                frame->error_code);
 }
 
 
 static bool
-setup_for_thread(char *arg, Thread **_thread, uint32 *_ebp,
-       uint32 *_oldPageDirectory)
+setup_for_thread(char* arg, Thread** _thread, addr_t* _bp,
+       phys_addr_t* _oldPageDirectory)
 {
-       Thread *thread = NULL;
+       Thread* thread = NULL;
 
        if (arg != NULL) {
                thread_id id = strtoul(arg, NULL, 0);
                thread = Thread::GetDebug(id);
                if (thread == NULL) {
-                       kprintf("could not find thread %ld\n", id);
+                       kprintf("could not find thread %" B_PRId32 "\n", id);
                        return false;
                }
 
                if (id != thread_get_current_thread_id()) {
                        // switch to the page directory of the new thread to be
                        // able to follow the stack trace into userland
-                       uint32 newPageDirectory = x86_next_page_directory(
+                       phys_addr_t newPageDirectory = x86_next_page_directory(
                                thread_get_current_thread(), thread);
 
                        if (newPageDirectory != 0) {
@@ -413,10 +457,10 @@ setup_for_thread(char *arg, Thread **_thread, uint32 
*_ebp,
                                        thread->cpu->cpu_num);
                                if (registers == NULL)
                                        return false;
-                               *_ebp = registers->bp;
+                               *_bp = registers->bp;
                        } else {
-                               // read %ebp from the thread's stack stored by 
a pushad
-                               *_ebp = thread->arch_info.current_stack.esp[2];
+                               // Read frame pointer from the thread's stack.
+                               *_bp = thread->arch_info.GetFramePointer();
                        }
                } else
                        thread = NULL;
@@ -474,13 +518,13 @@ is_iframe(Thread* thread, addr_t frame)
 }
 
 
-static struct iframe *
-find_previous_iframe(Thread *thread, addr_t frame)
+static iframe*
+find_previous_iframe(Thread* thread, addr_t frame)
 {
        // iterate backwards through the stack frames, until we hit an iframe
        while (is_kernel_stack_address(thread, frame)) {
                if (is_iframe(thread, frame))
-                       return (struct iframe*)frame;
+                       return (iframe*)frame;
 
                frame = *(addr_t*)frame;
        }
@@ -489,8 +533,8 @@ find_previous_iframe(Thread *thread, addr_t frame)
 }
 
 
-static struct iframe*
-get_previous_iframe(Thread* thread, struct iframe* frame)
+static iframe*
+get_previous_iframe(Thread* thread, iframe* frame)
 {
        if (frame == NULL)
                return NULL;
@@ -499,90 +543,83 @@ get_previous_iframe(Thread* thread, struct iframe* frame)
 }
 
 
-static struct iframe*
+static iframe*
 get_current_iframe(Thread* thread)
 {
        if (thread == thread_get_current_thread())
                return x86_get_current_iframe();
 
-       addr_t ebp = thread->arch_info.current_stack.esp[2];
-               // NOTE: This doesn't work, if the thread is running (on 
another CPU).
-       return find_previous_iframe(thread, ebp);
+       // NOTE: This doesn't work, if the thread is running (on another CPU).
+       return find_previous_iframe(thread, 
thread->arch_info.GetFramePointer());
 }
 
 
-uint32*
+#define CHECK_DEBUG_VARIABLE(_name, _member, _settable) \
+       if (strcmp(variableName, _name) == 0) { \
+               settable = _settable; \
+               return &_member; \
+       }
+
+
+static size_t*
 find_debug_variable(const char* variableName, bool& settable)
 {
-       struct iframe* frame = get_current_iframe(debug_get_debugged_thread());
+       iframe* frame = get_current_iframe(debug_get_debugged_thread());
        if (frame == NULL)
                return NULL;
 
-       settable = false;
-
-       if (strcmp(variableName, "gs") == 0) {
-               return &frame->gs;
-       } else if (strcmp(variableName, "fs") == 0) {
-               return &frame->fs;
-       } else if (strcmp(variableName, "es") == 0) {
-               return &frame->es;
-       } else if (strcmp(variableName, "ds") == 0) {
-               return &frame->ds;
-       } else if (strcmp(variableName, "cs") == 0) {
-               return &frame->cs;
-       } else if (strcmp(variableName, "edi") == 0) {
-               settable = true;
-               return &frame->di;
-       } else if (strcmp(variableName, "esi") == 0) {
-               settable = true;
-               return &frame->si;
-       } else if (strcmp(variableName, "ebp") == 0) {
-               settable = true;
-               return &frame->bp;
-       } else if (strcmp(variableName, "esp") == 0) {
-               settable = true;
-               return &frame->sp;
-       } else if (strcmp(variableName, "ebx") == 0) {
-               settable = true;
-               return &frame->bx;
-       } else if (strcmp(variableName, "edx") == 0) {
-               settable = true;
-               return &frame->dx;
-       } else if (strcmp(variableName, "ecx") == 0) {
-               settable = true;
-               return &frame->cx;
-       } else if (strcmp(variableName, "eax") == 0) {
-               settable = true;
-               return &frame->ax;
-       } else if (strcmp(variableName, "orig_eax") == 0) {
-               settable = true;
-               return &frame->orig_eax;
-       } else if (strcmp(variableName, "orig_edx") == 0) {
-               settable = true;
-               return &frame->orig_edx;
-       } else if (strcmp(variableName, "eip") == 0) {
-               settable = true;
-               return &frame->ip;
-       } else if (strcmp(variableName, "eflags") == 0) {
-               settable = true;
-               return &frame->flags;
-       }
+#ifdef __x86_64__
+       CHECK_DEBUG_VARIABLE("cs", frame->cs, false);
+       CHECK_DEBUG_VARIABLE("ss", frame->ss, false);
+       CHECK_DEBUG_VARIABLE("r15", frame->r15, true);
+       CHECK_DEBUG_VARIABLE("r14", frame->r14, true);
+       CHECK_DEBUG_VARIABLE("r13", frame->r13, true);
+       CHECK_DEBUG_VARIABLE("r12", frame->r12, true);
+       CHECK_DEBUG_VARIABLE("r11", frame->r11, true);
+       CHECK_DEBUG_VARIABLE("r10", frame->r10, true);
+       CHECK_DEBUG_VARIABLE("r9", frame->r9, true);
+       CHECK_DEBUG_VARIABLE("r8", frame->r8, true);
+       CHECK_DEBUG_VARIABLE("rbp", frame->bp, true);
+       CHECK_DEBUG_VARIABLE("rsi", frame->si, true);
+       CHECK_DEBUG_VARIABLE("rdi", frame->di, true);
+       CHECK_DEBUG_VARIABLE("rdx", frame->dx, true);
+       CHECK_DEBUG_VARIABLE("rcx", frame->cx, true);
+       CHECK_DEBUG_VARIABLE("rbx", frame->bx, true);
+       CHECK_DEBUG_VARIABLE("rax", frame->ax, true);
+       CHECK_DEBUG_VARIABLE("rip", frame->ip, true);
+       CHECK_DEBUG_VARIABLE("rflags", frame->flags, true);
+       CHECK_DEBUG_VARIABLE("rsp", frame->sp, true);
+#else
+       CHECK_DEBUG_VARIABLE("gs", frame->gs, false);
+       CHECK_DEBUG_VARIABLE("fs", frame->fs, false);
+       CHECK_DEBUG_VARIABLE("es", frame->es, false);
+       CHECK_DEBUG_VARIABLE("ds", frame->ds, false);
+       CHECK_DEBUG_VARIABLE("cs", frame->cs, false);
+       CHECK_DEBUG_VARIABLE("edi", frame->di, true);
+       CHECK_DEBUG_VARIABLE("esi", frame->si, true);
+       CHECK_DEBUG_VARIABLE("ebp", frame->bp, true);
+       CHECK_DEBUG_VARIABLE("esp", frame->sp, true);
+       CHECK_DEBUG_VARIABLE("ebx", frame->bx, true);
+       CHECK_DEBUG_VARIABLE("edx", frame->dx, true);
+       CHECK_DEBUG_VARIABLE("ecx", frame->cx, true);
+       CHECK_DEBUG_VARIABLE("eax", frame->ax, true);
+       CHECK_DEBUG_VARIABLE("orig_eax", frame->orig_eax, true);
+       CHECK_DEBUG_VARIABLE("orig_edx", frame->orig_edx, true);
+       CHECK_DEBUG_VARIABLE("eip", frame->ip, true);
+       CHECK_DEBUG_VARIABLE("eflags", frame->flags, true);
 
        if (IFRAME_IS_USER(frame)) {
-               if (strcmp(variableName, "user_esp") == 0) {
-                       settable = true;
-                       return &frame->user_sp;
-               } else if (strcmp(variableName, "user_ss") == 0) {
-                       return &frame->user_ss;
-               }
+               CHECK_DEBUG_VARIABLE("user_esp", frame->user_sp, true);
+               CHECK_DEBUG_VARIABLE("user_ss", frame->user_ss, false);
        }
+#endif
 
        return NULL;
 }
 
 
 static int
-stack_trace(int argc, char **argv)
+stack_trace(int argc, char** argv)
 {
        static const char* usage = "usage: %s [-d] [ <thread id> ]\n"
                "Prints a stack trace for the current, respectively the 
specified\n"
@@ -603,68 +640,69 @@ stack_trace(int argc, char **argv)
                return 0;
        }
 
-       uint32 previousLocations[NUM_PREVIOUS_LOCATIONS];
-       Thread *thread = NULL;
-       uint32 oldPageDirectory = 0;
-       uint32 ebp = x86_get_stack_frame();
+       addr_t previousLocations[NUM_PREVIOUS_LOCATIONS];
+       Thread* thread = NULL;
+       phys_addr_t oldPageDirectory = 0;
+       addr_t bp = x86_get_stack_frame();
        int32 num = 0, last = 0;
 
        if (!setup_for_thread(argc == threadIndex + 1 ? argv[threadIndex] : 
NULL,
-                       &thread, &ebp, &oldPageDirectory))
+                       &thread, &bp, &oldPageDirectory))
                return 0;
 
        DebuggedThreadSetter threadSetter(thread);
 
        if (thread != NULL) {
-               kprintf("stack trace for thread %ld \"%s\"\n", thread->id,
+               kprintf("stack trace for thread %" B_PRId32 " \"%s\"\n", 
thread->id,
                        thread->name);
 
                kprintf("    kernel stack: %p to %p\n",
-                       (void *)thread->kernel_stack_base,
-                       (void *)(thread->kernel_stack_top));
+                       (void*)thread->kernel_stack_base,
+                       (void*)(thread->kernel_stack_top));
                if (thread->user_stack_base != 0) {
                        kprintf("      user stack: %p to %p\n",
-                               (void *)thread->user_stack_base,
-                               (void *)(thread->user_stack_base + 
thread->user_stack_size));
+                               (void*)thread->user_stack_base,
+                               (void*)(thread->user_stack_base + 
thread->user_stack_size));
                }
        }
 
-       kprintf("frame               caller     <image>:function + offset\n");
+       kprintf("%-*s            %-*s   <image>:function + offset\n",
+               B_PRINTF_POINTER_WIDTH, "frame", B_PRINTF_POINTER_WIDTH, 
"caller");
 
        bool onKernelStack = true;
 
        for (int32 callIndex = 0;; callIndex++) {
                onKernelStack = onKernelStack
-                       && is_kernel_stack_address(thread, ebp);
+                       && is_kernel_stack_address(thread, bp);
 
-               if (onKernelStack && is_iframe(thread, ebp)) {
-                       struct iframe *frame = (struct iframe *)ebp;
+               if (onKernelStack && is_iframe(thread, bp)) {
+                       iframe* frame = (iframe*)bp;
 
                        print_iframe(frame);
-                       print_stack_frame(thread, frame->ip, ebp, frame->bp, 
callIndex,
+                       print_stack_frame(thread, frame->ip, bp, frame->bp, 
callIndex,
                                demangle);
 
-                       ebp = frame->bp;
+                       bp = frame->bp;
                } else {
-                       addr_t eip, nextEbp;
+                       addr_t ip, nextBp;
 
-                       if (get_next_frame_debugger(ebp, &nextEbp, &eip) != 
B_OK) {
-                               kprintf("%08lx -- read fault\n", ebp);
+                       if (get_next_frame_debugger(bp, &nextBp, &ip) != B_OK) {
+                               kprintf("%0*lx -- read fault\n", 
B_PRINTF_POINTER_WIDTH, bp);
                                break;
                        }
 
-                       if (eip == 0 || ebp == 0)
+                       if (ip == 0 || bp == 0)
                                break;
 
-                       print_stack_frame(thread, eip, ebp, nextEbp, callIndex, 
demangle);
-                       ebp = nextEbp;
+                       print_stack_frame(thread, ip, bp, nextBp, callIndex, 
demangle);
+                       bp = nextBp;
                }
 
-               if (already_visited(previousLocations, &last, &num, ebp)) {
-                       kprintf("circular stack frame: %p!\n", (void *)ebp);
+               if (already_visited(previousLocations, &last, &num, bp)) {
+                       kprintf("circular stack frame: %p!\n", (void*)bp);
                        break;
                }
-               if (ebp == 0)
+               if (bp == 0)
                        break;
        }
 
@@ -677,6 +715,7 @@ stack_trace(int argc, char **argv)
 }
 
 
+#ifndef __x86_64__
 static void
 print_call(Thread *thread, addr_t eip, addr_t ebp, addr_t nextEbp,
        int32 argCount)
@@ -759,7 +798,7 @@ show_call(int argc, char **argv)
        }
 
        Thread *thread = NULL;
-       uint32 oldPageDirectory = 0;
+       phys_addr_t oldPageDirectory = 0;
        addr_t ebp = x86_get_stack_frame();
        int32 argCount = 0;
 
@@ -835,10 +874,11 @@ show_call(int argc, char **argv)
 
        return 0;
 }
+#endif
 
 
 static int
-dump_iframes(int argc, char **argv)
+dump_iframes(int argc, char** argv)
 {
        static const char* usage = "usage: %s [ <thread id> ]\n"
                "Prints the iframe stack for the current, respectively the 
specified\n"
@@ -850,7 +890,7 @@ dump_iframes(int argc, char **argv)
                return 0;
        }
 
-       Thread *thread = NULL;
+       Thread* thread = NULL;
 
        if (argc < 2) {
                thread = thread_get_current_thread();
@@ -858,7 +898,7 @@ dump_iframes(int argc, char **argv)
                thread_id id = strtoul(argv[1], NULL, 0);
                thread = Thread::GetDebug(id);
                if (thread == NULL) {
-                       kprintf("could not find thread %ld\n", id);
+                       kprintf("could not find thread %" B_PRId32 "\n", id);
                        return 0;
                }
        } else if (argc > 2) {
@@ -866,12 +906,14 @@ dump_iframes(int argc, char **argv)
                return 0;
        }
 
-       if (thread != NULL)
-               kprintf("iframes for thread %ld \"%s\"\n", thread->id, 
thread->name);
+       if (thread != NULL) {
+               kprintf("iframes for thread %" B_PRId32 " \"%s\"\n", thread->id,
+                       thread->name);
+       }
 
        DebuggedThreadSetter threadSetter(thread);
 
-       struct iframe* frame = find_previous_iframe(thread, 
x86_get_stack_frame());
+       iframe* frame = find_previous_iframe(thread, x86_get_stack_frame());
        while (frame != NULL) {
                print_iframe(frame);
                frame = get_previous_iframe(thread, frame);
@@ -882,17 +924,17 @@ dump_iframes(int argc, char **argv)
 
 
 static bool
-is_calling(Thread *thread, addr_t eip, const char *pattern,
-       addr_t start, addr_t end)
+is_calling(Thread* thread, addr_t ip, const char* pattern, addr_t start,
+       addr_t end)
 {
        if (pattern == NULL)
-               return eip >= start && eip < end;
+               return ip >= start && ip < end;
 
-       if (!IS_KERNEL_ADDRESS(eip))
+       if (!IS_KERNEL_ADDRESS(ip))
                return false;
 
-       const char *symbol;
-       if (lookup_symbol(thread, eip, NULL, &symbol, NULL, NULL) != B_OK)
+       const char* symbol;
+       if (lookup_symbol(thread, ip, NULL, &symbol, NULL, NULL) != B_OK)
                return false;
 
        return strstr(symbol, pattern);
@@ -933,9 +975,9 @@ cmd_in_context(int argc, char** argv)
        }
 
        // switch the page directory, if necessary
-       uint32 oldPageDirectory = 0;
+       phys_addr_t oldPageDirectory = 0;
        if (thread != thread_get_current_thread()) {
-               uint32 newPageDirectory = x86_next_page_directory(
+               phys_addr_t newPageDirectory = x86_next_page_directory(
                        thread_get_current_thread(), thread);
 
                if (newPageDirectory != 0) {
@@ -962,7 +1004,7 @@ cmd_in_context(int argc, char** argv)
 
 
 void
-arch_debug_save_registers(struct arch_debug_registers* registers)
+arch_debug_save_registers(arch_debug_registers* registers)
 {
        // get the caller's frame pointer
        stack_frame* frame = (stack_frame*)x86_get_stack_frame();
@@ -978,14 +1020,14 @@ arch_debug_stack_trace(void)
 
 
 bool
-arch_debug_contains_call(Thread *thread, const char *symbol,
-       addr_t start, addr_t end)
+arch_debug_contains_call(Thread* thread, const char* symbol, addr_t start,
+       addr_t end)
 {
        DebuggedThreadSetter threadSetter(thread);
 
-       addr_t ebp;
+       addr_t bp;
        if (thread == thread_get_current_thread())
-               ebp = x86_get_stack_frame();
+               bp = x86_get_stack_frame();
        else {
                if (thread->state == B_THREAD_RUNNING) {
                        // The thread is currently running on another CPU.
@@ -995,38 +1037,38 @@ arch_debug_contains_call(Thread *thread, const char 
*symbol,
                                thread->cpu->cpu_num);
                        if (registers == NULL)
                                return false;
-                       ebp = registers->bp;
+                       bp = registers->bp;
                } else {
                        // thread not running
-                       ebp = thread->arch_info.current_stack.esp[2];
+                       bp = thread->arch_info.GetFramePointer();
                }
        }
 
        for (;;) {
-               if (!is_kernel_stack_address(thread, ebp))
+               if (!is_kernel_stack_address(thread, bp))
                        break;
 
-               if (is_iframe(thread, ebp)) {
-                       struct iframe *frame = (struct iframe *)ebp;
+               if (is_iframe(thread, bp)) {
+                       iframe* frame = (iframe*)bp;
 
                        if (is_calling(thread, frame->ip, symbol, start, end))
                                return true;
 
-                       ebp = frame->bp;
+                       bp = frame->bp;
                } else {
-                       addr_t eip, nextEbp;
+                       addr_t ip, nextBp;
 
-                       if (get_next_frame_no_debugger(ebp, &nextEbp, &eip) != 
B_OK
-                               || eip == 0 || ebp == 0)
+                       if (get_next_frame_no_debugger(bp, &nextBp, &ip) != B_OK
+                               || ip == 0 || bp == 0)
                                break;
 
-                       if (is_calling(thread, eip, symbol, start, end))
+                       if (is_calling(thread, ip, symbol, start, end))
                                return true;
 
-                       ebp = nextEbp;
+                       bp = nextBp;
                }
 
-               if (ebp == 0)
+               if (bp == 0)
                        break;
        }
 
@@ -1034,11 +1076,11 @@ arch_debug_contains_call(Thread *thread, const char 
*symbol,
 }
 
 
-void *
+void*
 arch_debug_get_caller(void)
 {
-       struct stack_frame *frame = (struct stack_frame *)x86_get_stack_frame();
-       return (void *)frame->previous->return_address;
+       stack_frame* frame = (stack_frame*)x86_get_stack_frame();
+       return (void*)frame->previous->return_address;
 }
 
 
@@ -1064,39 +1106,39 @@ arch_debug_get_stack_trace(addr_t* returnAddresses, 
int32 maxCount,
 
        Thread* thread = thread_get_current_thread();
        int32 count = 0;
-       addr_t ebp = x86_get_stack_frame();
+       addr_t bp = x86_get_stack_frame();
        bool onKernelStack = true;
 
-       while (ebp != 0 && count < maxCount) {
+       while (bp != 0 && count < maxCount) {
                onKernelStack = onKernelStack
-                       && is_kernel_stack_address(thread, ebp);
+                       && is_kernel_stack_address(thread, bp);
                if (!onKernelStack && (flags & STACK_TRACE_USER) == 0)
                        break;
 
-               addr_t eip;
-               addr_t nextEbp;
+               addr_t ip;
+               addr_t nextBp;
 
-               if (onKernelStack && is_iframe(thread, ebp)) {
-                       struct iframe *frame = (struct iframe*)ebp;
-                       eip = frame->ip;
-                       nextEbp = frame->bp;
+               if (onKernelStack && is_iframe(thread, bp)) {
+                       iframe* frame = (iframe*)bp;
+                       ip = frame->ip;
+                       nextBp = frame->bp;
 
                        if (skipIframes > 0) {
                                if (--skipIframes == 0)
                                        skipFrames = 0;
                        }
                } else {
-                       if (get_next_frame_no_debugger(ebp, &nextEbp, &eip) != 
B_OK)
+                       if (get_next_frame_no_debugger(bp, &nextBp, &ip) != 
B_OK)
                                break;
                }
 
                if (skipFrames <= 0
                        && ((flags & STACK_TRACE_KERNEL) != 0 || 
onKernelStack)) {
-                       returnAddresses[count++] = eip;
+                       returnAddresses[count++] = ip;
                } else
                        skipFrames--;
 
-               ebp = nextEbp;
+               bp = nextBp;
        }
 
        return count;
@@ -1112,12 +1154,12 @@ arch_debug_get_stack_trace(addr_t* returnAddresses, 
int32 maxCount,
 void*
 arch_debug_get_interrupt_pc(bool* _isSyscall)
 {
-       struct iframe* frame = get_current_iframe(debug_get_debugged_thread());
+       iframe* frame = get_current_iframe(debug_get_debugged_thread());
        if (frame == NULL)
                return NULL;
 
        if (_isSyscall != NULL)
-               *_isSyscall = frame->vector == 99;
+               *_isSyscall = frame->type == IFRAME_TYPE_SYSCALL;
 
        return (void*)(addr_t)frame->ip;
 }
@@ -1129,7 +1171,14 @@ arch_debug_get_interrupt_pc(bool* _isSyscall)
 void
 arch_debug_unset_current_thread(void)
 {
+#ifdef __x86_64__
+       // Can't just write 0 to the GS base, that will cause the read from 
%gs:0
+       // to fault. Instead point it at a NULL pointer, %gs:0 will get this 
value.
+       static Thread* unsetThread = NULL;
+       x86_write_msr(IA32_MSR_GS_BASE, (addr_t)&unsetThread);
+#else
        x86_write_dr3(NULL);
+#endif
 }
 
 
@@ -1145,14 +1194,14 @@ status_t
 arch_set_debug_variable(const char* variableName, uint64 value)
 {
        bool settable;
-       uint32* variable = find_debug_variable(variableName, settable);
+       size_t* variable = find_debug_variable(variableName, settable);
        if (variable == NULL)
                return B_ENTRY_NOT_FOUND;
 
        if (!settable)
                return B_NOT_ALLOWED;
 
-       *variable = (uint32)value;
+       *variable = (size_t)value;
        return B_OK;
 }
 
@@ -1161,7 +1210,7 @@ status_t
 arch_get_debug_variable(const char* variableName, uint64* value)
 {
        bool settable;
-       uint32* variable = find_debug_variable(variableName, settable);
+       size_t* variable = find_debug_variable(variableName, settable);
        if (variable == NULL)
                return B_ENTRY_NOT_FOUND;
 
@@ -1170,6 +1219,12 @@ arch_get_debug_variable(const char* variableName, 
uint64* value)
 }
 
 
+struct gdb_register {
+       int32 type;
+       int64 value;
+};
+
+
 /*!    Writes the contents of the CPU registers at some fixed outer stack 
frame or
        iframe into the given buffer in the format expected by gdb.
 
@@ -1183,10 +1238,36 @@ arch_get_debug_variable(const char* variableName, 
uint64* value)
 ssize_t
 arch_debug_gdb_get_registers(char* buffer, size_t bufferSize)
 {
-       struct iframe* frame = get_current_iframe(debug_get_debugged_thread());
+       iframe* frame = get_current_iframe(debug_get_debugged_thread());
        if (frame == NULL)
                return B_NOT_SUPPORTED;
 
+#ifdef __x86_64__
+       // For x86_64 the register order is:
+       //
+       //    rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp,
+       //    r8, r9, r10, r11, r12, r13, r14, r15,
+       //    rip, rflags, cs, ss, ds, es, fs, gs
+       //
+       // Annoyingly, GDB wants all the registers as 64-bit values, but then
+       // RFLAGS and the segment registers as 32-bit values, hence the need for
+       // the type information.
+       static const int32 kRegisterCount = 24;
+       gdb_register registers[kRegisterCount] = {
+               { B_UINT64_TYPE, frame->ax },  { B_UINT64_TYPE, frame->bx },
+               { B_UINT64_TYPE, frame->cx },  { B_UINT64_TYPE, frame->dx },
+               { B_UINT64_TYPE, frame->si },  { B_UINT64_TYPE, frame->di },
+               { B_UINT64_TYPE, frame->bp },  { B_UINT64_TYPE, frame->sp },
+               { B_UINT64_TYPE, frame->r8 },  { B_UINT64_TYPE, frame->r9 },
+               { B_UINT64_TYPE, frame->r10 }, { B_UINT64_TYPE, frame->r11 },
+               { B_UINT64_TYPE, frame->r12 }, { B_UINT64_TYPE, frame->r13 },
+               { B_UINT64_TYPE, frame->r14 }, { B_UINT64_TYPE, frame->r15 },
+               { B_UINT64_TYPE, frame->ip },  { B_UINT32_TYPE, frame->flags },
+               { B_UINT32_TYPE, frame->cs },  { B_UINT32_TYPE, frame->ss },
+               { B_UINT32_TYPE, 0 }, { B_UINT32_TYPE, 0 },
+               { B_UINT32_TYPE, 0 }, { B_UINT32_TYPE, 0 },
+       };
+#else
        // For x86 the register order is:
        //
        //    eax, ecx, edx, ebx,
@@ -1195,23 +1276,36 @@ arch_debug_gdb_get_registers(char* buffer, size_t 
bufferSize)
        //    cs, ss, ds, es, fs, gs
        //
        // Note that even though the segment descriptors are actually 16 bits 
wide,
-       // gdb requires them as 32 bit integers. Note also that for some reason
-       // gdb wants the register dump in *big endian* format.
+       // gdb requires them as 32 bit integers.
        static const int32 kRegisterCount = 16;
-       uint32 registers[kRegisterCount] = {
-               frame->ax, frame->cx, frame->dx, frame->bx,
-               frame->sp, frame->bp, frame->si, frame->di,
-               frame->ip, frame->flags,
-               frame->cs, frame->ds, frame->ds, frame->es,
+       gdb_register registers[kRegisterCount] = {
+               { B_UINT32_TYPE, frame->ax }, { B_UINT32_TYPE, frame->cx },
+               { B_UINT32_TYPE, frame->dx }, { B_UINT32_TYPE, frame->bx },
+               { B_UINT32_TYPE, frame->sp }, { B_UINT32_TYPE, frame->bp },
+               { B_UINT32_TYPE, frame->si }, { B_UINT32_TYPE, frame->di },
+               { B_UINT32_TYPE, frame->ip }, { B_UINT32_TYPE, frame->flags },
+               { B_UINT32_TYPE, frame->cs }, { B_UINT32_TYPE, frame->ds },
                        // assume ss == ds
-               frame->fs, frame->gs
+               { B_UINT32_TYPE, frame->ds }, { B_UINT32_TYPE, frame->es },
+               { B_UINT32_TYPE, frame->fs }, { B_UINT32_TYPE, frame->gs },
        };
+#endif
 
        const char* const bufferStart = buffer;
 
        for (int32 i = 0; i < kRegisterCount; i++) {
-               int result = snprintf(buffer, bufferSize, "%08" B_PRIx32,
-                       B_HOST_TO_BENDIAN_INT32(registers[i]));
+               // For some reason gdb wants the register dump in *big endian* 
format.
+               int result = 0;
+               switch (registers[i].type) {
+                       case B_UINT64_TYPE:
+                               result = snprintf(buffer, bufferSize, "%016" 
B_PRIx64,
+                                       
B_HOST_TO_BENDIAN_INT64(registers[i].value));
+                               break;
+                       case B_UINT32_TYPE:
+                               result = snprintf(buffer, bufferSize, "%08" 
B_PRIx32,
+                                       
B_HOST_TO_BENDIAN_INT32((uint32)registers[i].value));
+                               break;
+               }
                if (result >= (int)bufferSize)
                        return B_BUFFER_OVERFLOW;
 
@@ -1224,7 +1318,7 @@ arch_debug_gdb_get_registers(char* buffer, size_t 
bufferSize)
 
 
 status_t
-arch_debug_init(kernel_args *args)
+arch_debug_init(kernel_args* args)
 {
        // at this stage, the debugger command system is alive
 
@@ -1234,7 +1328,9 @@ arch_debug_init(kernel_args *args)
                "Stack crawl for current thread (or any other)");
        add_debugger_command("iframe", &dump_iframes,
                "Dump iframes for the specified thread");
+#ifndef __x86_64__
        add_debugger_command("call", &show_call, "Show call with arguments");
+#endif
        add_debugger_command_etc("in_context", &cmd_in_context,
                "Executes a command in the context of a given thread",
                "<thread ID> <command> ...\n"
diff --git a/src/system/kernel/arch/x86/arch_thread.cpp 
b/src/system/kernel/arch/x86/arch_thread.cpp
index d0a1769..401f9d4 100644
--- a/src/system/kernel/arch/x86/arch_thread.cpp
+++ b/src/system/kernel/arch/x86/arch_thread.cpp
@@ -108,15 +108,9 @@ x86_get_thread_user_iframe(Thread *thread)
        if (thread->state == B_THREAD_RUNNING)
                return NULL;
 
-       // Read frame pointer from the thread's stack.
-#ifdef __x86_64__
-       addr_t bp = thread->arch_info.current_stack[1];
-#else
-       addr_t bp = thread->arch_info.current_stack.esp[2];
-#endif
-
        // find the user iframe
-       struct iframe* frame = find_previous_iframe(thread, bp);
+       struct iframe* frame = find_previous_iframe(thread,
+               thread->arch_info.GetFramePointer());
 
        while (frame != NULL) {
                if (IFRAME_IS_USER(frame))
@@ -136,7 +130,7 @@ x86_get_current_iframe(void)
 
 
 phys_addr_t
-x86_next_page_directory(Thread *from, Thread *to)
+x86_next_page_directory(Thread* from, Thread* to)
 {
        VMAddressSpace* toAddressSpace = to->team->address_space;
        if (from->team->address_space == toAddressSpace) {


Other related posts: