Implemented user debugging support for x86_64.

Reused x86 arch_user_debugger.cpp, with a few minor changes to make
the code work for both 32 and 64 bit. Something isn't quite working
right, if a breakpoint is hit the kernel will hang. Other than that
everything appears to work correctly.
This commit is contained in:
Alex Smith
2012-08-07 20:20:42 +01:00
parent 2b883e1977
commit 8a1903353e
12 changed files with 352 additions and 380 deletions
+1 -3
View File
@@ -32,7 +32,7 @@ typedef struct x86_64_extended_registers {
x86_64_fp_register mmx_registers[8]; // mm0-mm7 x86_64_fp_register mmx_registers[8]; // mm0-mm7
}; };
x86_64_xmm_register xmm_registers[16]; // xmm0-xmm15 x86_64_xmm_register xmm_registers[16]; // xmm0-xmm15
uint8 reserved4[96]; // 416 - 512 uint8 reserved2[96]; // 416 - 512
} x86_64_extended_registers; } x86_64_extended_registers;
@@ -58,8 +58,6 @@ struct x86_64_debug_cpu_state {
uint64 rcx; uint64 rcx;
uint64 rbx; uint64 rbx;
uint64 rax; uint64 rax;
uint64 vector;
uint64 error_code;
uint64 rip; uint64 rip;
uint64 cs; uint64 cs;
uint64 rflags; uint64 rflags;
+2 -2
View File
@@ -263,8 +263,8 @@ typedef struct arch_cpu_info {
struct X86PagingStructures* active_paging_structures; struct X86PagingStructures* active_paging_structures;
uint32 dr6; // temporary storage for debug registers (cf. size_t dr6; // temporary storage for debug registers (cf.
uint32 dr7; // x86_exit_user_debug_at_kernel_entry()) size_t dr7; // x86_exit_user_debug_at_kernel_entry())
// local TSS for this cpu // local TSS for this cpu
struct tss tss; struct tss tss;
@@ -9,8 +9,12 @@
#define ARCH_INIT_USER_DEBUG x86_init_user_debug #define ARCH_INIT_USER_DEBUG x86_init_user_debug
// number of breakpoints the CPU supports // number of breakpoints the CPU supports
// Actually it supports 4, but DR3 is used to hold the Thread*. // On 32-bit, DR3 is used to hold the Thread*.
#define X86_BREAKPOINT_COUNT 3 #ifdef __x86_64__
# define X86_BREAKPOINT_COUNT 4
#else
# define X86_BREAKPOINT_COUNT 3
#endif
// debug status register DR6 // debug status register DR6
enum { enum {
@@ -95,14 +99,14 @@ enum {
struct arch_breakpoint { struct arch_breakpoint {
void *address; // NULL, if deactivated void *address; // NULL, if deactivated
uint32 type; // one of the architecture types above size_t type; // one of the architecture types above
uint32 length; // one of the length values above size_t length; // one of the length values above
}; };
struct arch_team_debug_info { struct arch_team_debug_info {
struct arch_breakpoint breakpoints[X86_BREAKPOINT_COUNT]; struct arch_breakpoint breakpoints[X86_BREAKPOINT_COUNT];
uint32 dr7; // debug control register DR7 size_t dr7; // debug control register DR7
}; };
struct arch_thread_debug_info { struct arch_thread_debug_info {
+4 -3
View File
@@ -9,6 +9,7 @@
#define _KERNEL_ELF_H #define _KERNEL_ELF_H
#include <elf_common.h>
#include <thread.h> #include <thread.h>
#include <image.h> #include <image.h>
@@ -49,9 +50,9 @@ status_t elf_add_memory_image_symbol(image_id id, const char* name,
addr_t address, size_t size, int32 type); addr_t address, size_t size, int32 type);
status_t elf_init(struct kernel_args *args); status_t elf_init(struct kernel_args *args);
status_t _user_read_kernel_image_symbols(image_id id, status_t _user_read_kernel_image_symbols(image_id id, elf_sym* symbolTable,
struct Elf32_Sym* symbolTable, int32* _symbolCount, int32* _symbolCount, char* stringTable, size_t* _stringTableSize,
char* stringTable, size_t* _stringTableSize, addr_t* _imageDelta); addr_t* _imageDelta);
#ifdef __cplusplus #ifdef __cplusplus
} }
+2 -2
View File
@@ -8,6 +8,7 @@
#include <arch_config.h> #include <arch_config.h>
#include <DiskDeviceDefs.h> #include <DiskDeviceDefs.h>
#include <elf_common.h>
#include <image.h> #include <image.h>
#include <OS.h> #include <OS.h>
@@ -21,7 +22,6 @@ extern "C" {
struct attr_info; struct attr_info;
struct dirent; struct dirent;
struct Elf32_Sym;
struct fd_info; struct fd_info;
struct fd_set; struct fd_set;
struct fs_info; struct fs_info;
@@ -226,7 +226,7 @@ extern status_t _kern_get_image_info(image_id id, image_info *info,
extern status_t _kern_get_next_image_info(team_id team, int32 *cookie, extern status_t _kern_get_next_image_info(team_id team, int32 *cookie,
image_info *info, size_t size); image_info *info, size_t size);
extern status_t _kern_read_kernel_image_symbols(image_id id, extern status_t _kern_read_kernel_image_symbols(image_id id,
struct Elf32_Sym* symbolTable, int32* _symbolCount, elf_sym* symbolTable, int32* _symbolCount,
char* stringTable, size_t* _stringTableSize, char* stringTable, size_t* _stringTableSize,
addr_t* _imageDelta); addr_t* _imageDelta);
+2 -4
View File
@@ -72,11 +72,9 @@ arch_int_init(kernel_args* args)
table[i] = x86_hardware_interrupt; table[i] = x86_hardware_interrupt;
table[0] = x86_unexpected_exception; // Divide Error Exception (#DE) table[0] = x86_unexpected_exception; // Divide Error Exception (#DE)
//table[1] = x86_handle_debug_exception; // Debug Exception (#DB) table[1] = x86_handle_debug_exception; // Debug Exception (#DB)
table[1] = x86_unexpected_exception;
table[2] = x86_fatal_exception; // NMI Interrupt table[2] = x86_fatal_exception; // NMI Interrupt
//table[3] = x86_handle_breakpoint_exception; // Breakpoint Exception (#BP) table[3] = x86_handle_breakpoint_exception; // Breakpoint Exception (#BP)
table[3] = x86_unexpected_exception;
table[4] = x86_unexpected_exception; // Overflow Exception (#OF) table[4] = x86_unexpected_exception; // Overflow Exception (#OF)
table[5] = x86_unexpected_exception; // BOUND Range Exceeded Exception (#BR) table[5] = x86_unexpected_exception; // BOUND Range Exceeded Exception (#BR)
table[6] = x86_unexpected_exception; // Invalid Opcode Exception (#UD) table[6] = x86_unexpected_exception; // Invalid Opcode Exception (#UD)
+57 -40
View File
@@ -109,17 +109,12 @@
\ \
UNLOCK_THREAD_TIME() UNLOCK_THREAD_TIME()
// TODO
#if 0
#define STOP_USER_DEBUGGING() \ #define STOP_USER_DEBUGGING() \
testl $(THREAD_FLAGS_BREAKPOINTS_INSTALLED \ testl $(THREAD_FLAGS_BREAKPOINTS_INSTALLED \
| THREAD_FLAGS_SINGLE_STEP), THREAD_flags(%r12); \ | THREAD_FLAGS_SINGLE_STEP), THREAD_flags(%r12); \
jz 1f; \ jz 1f; \
call x86_exit_user_debug_at_kernel_entry; \ call x86_exit_user_debug_at_kernel_entry; \
1: 1:
#else
#define STOP_USER_DEBUGGING()
#endif
// The following code defines the interrupt service routines for all 256 // The following code defines the interrupt service routines for all 256
@@ -273,12 +268,12 @@ STATIC_FUNCTION(int_bottom_user):
call thread_at_kernel_exit_no_signals call thread_at_kernel_exit_no_signals
.Lkernel_exit_work_done: .Lkernel_exit_work_done:
// Install breakpoints, if defined. TODO // Install breakpoints, if defined.
//testl $THREAD_FLAGS_BREAKPOINTS_DEFINED, THREAD_flags(%r12) testl $THREAD_FLAGS_BREAKPOINTS_DEFINED, THREAD_flags(%r12)
//jz 1f jz 1f
//movq %rbp, %rdi movq %rbp, %rdi
//call x86_init_user_debug_at_kernel_exit call x86_init_user_debug_at_kernel_exit
//1: 1:
// Restore the saved registers. // Restore the saved registers.
RESTORE_IFRAME() RESTORE_IFRAME()
@@ -333,7 +328,7 @@ FUNCTION(x86_64_syscall_entry):
// Check whether the syscall number is valid. // Check whether the syscall number is valid.
cmpq $SYSCALL_COUNT, %r14 cmpq $SYSCALL_COUNT, %r14
jae .Lbad_syscall_number jae .Lsyscall_return
// Get the system call table entry. Note I'm hardcoding the shift because // Get the system call table entry. Note I'm hardcoding the shift because
// sizeof(syscall_info) is 16 and scale factors of 16 aren't supported, // sizeof(syscall_info) is 16 and scale factors of 16 aren't supported,
@@ -348,6 +343,11 @@ FUNCTION(x86_64_syscall_entry):
cmpq $48, %rcx cmpq $48, %rcx
ja .Lsyscall_stack_args ja .Lsyscall_stack_args
.Lperform_syscall:
testl $THREAD_FLAGS_DEBUGGER_INSTALLED, THREAD_flags(%r12)
jnz .Lpre_syscall_debug
.Lpre_syscall_debug_done:
// Restore the arguments from the iframe. UPDATE_THREAD_USER_TIME() makes // Restore the arguments from the iframe. UPDATE_THREAD_USER_TIME() makes
// 2 function calls which means they may have been overwritten. Note that // 2 function calls which means they may have been overwritten. Note that
// argument 4 is in R10 on the frame rather than RCX as RCX is used by // argument 4 is in R10 on the frame rather than RCX as RCX is used by
@@ -359,7 +359,7 @@ FUNCTION(x86_64_syscall_entry):
movq IFRAME_r8(%rbp), %r8 movq IFRAME_r8(%rbp), %r8
movq IFRAME_r9(%rbp), %r9 movq IFRAME_r9(%rbp), %r9
// TODO: pre-syscall tracing/debug // TODO: pre-syscall tracing
// Call the function and save its return value. // Call the function and save its return value.
call *SYSCALL_INFO_function(%rax) call *SYSCALL_INFO_function(%rax)
@@ -367,7 +367,9 @@ FUNCTION(x86_64_syscall_entry):
// TODO: post-syscall tracing // TODO: post-syscall tracing
.Lbad_syscall_number: // Restore the original stack pointer and return.
movq %rbp, %rsp
.Lsyscall_return: .Lsyscall_return:
// Clear the restarted flag. // Clear the restarted flag.
testl $THREAD_FLAGS_SYSCALL_RESTARTED, THREAD_flags(%r12) testl $THREAD_FLAGS_SYSCALL_RESTARTED, THREAD_flags(%r12)
@@ -405,9 +407,41 @@ FUNCTION(x86_64_syscall_entry):
swapgs swapgs
sysretq sysretq
.Lpost_syscall_work: .Lpre_syscall_debug:
// TODO: post-syscall debugging // user_debug_pre_syscall expects a pointer to a block of arguments, need
// to push the register arguments onto the stack.
push IFRAME_r9(%rbp)
push IFRAME_r8(%rbp)
push IFRAME_r10(%rbp)
push IFRAME_dx(%rbp)
push IFRAME_si(%rbp)
push IFRAME_di(%rbp)
movq %r14, %rdi // syscall number
movq %rsp, %rsi
push %rax
call user_debug_pre_syscall
pop %rax
addq $48, %rsp
jmp .Lpre_syscall_debug_done
.Lpost_syscall_work:
testl $THREAD_FLAGS_DEBUGGER_INSTALLED, THREAD_flags(%r12)
jz 1f
// Post-syscall debugging. Same as above, need a block of arguments.
push IFRAME_r9(%rbp)
push IFRAME_r8(%rbp)
push IFRAME_r10(%rbp)
push IFRAME_dx(%rbp)
push IFRAME_si(%rbp)
push IFRAME_di(%rbp)
movq %r14, %rdi // syscall number
movq %rsp, %rsi
movq IFRAME_ax(%rbp), %rdx // return value
movq %r13, %rcx // start time, preserved earlier
call user_debug_post_syscall
addq $48, %rsp
1:
// Do we need to handle signals? // Do we need to handle signals?
testl $(THREAD_FLAGS_SIGNALS_PENDING | THREAD_FLAGS_DEBUG_THREAD) \ testl $(THREAD_FLAGS_SIGNALS_PENDING | THREAD_FLAGS_DEBUG_THREAD) \
, THREAD_flags(%r12) , THREAD_flags(%r12)
@@ -422,11 +456,11 @@ FUNCTION(x86_64_syscall_entry):
movq %rsp, %rdi movq %rsp, %rdi
call x86_restart_syscall call x86_restart_syscall
1: 1:
// Install breakpoints, if defined. TODO // Install breakpoints, if defined.
//testl $THREAD_FLAGS_BREAKPOINTS_DEFINED, THREAD_flags(%r12) testl $THREAD_FLAGS_BREAKPOINTS_DEFINED, THREAD_flags(%r12)
//jz .Liret jz .Liret
//movq %rbp, %rdi movq %rbp, %rdi
//call x86_init_user_debug_at_kernel_exit call x86_init_user_debug_at_kernel_exit
// On this return path it is possible that the frame has been modified, // On this return path it is possible that the frame has been modified,
// for example to execute a signal handler. In this case it is safer to // for example to execute a signal handler. In this case it is safer to
@@ -470,25 +504,8 @@ FUNCTION(x86_64_syscall_entry):
movsq movsq
movq $0, THREAD_fault_handler(%r12) movq $0, THREAD_fault_handler(%r12)
// Restore the register arguments from the iframe. // Perform the call.
movq IFRAME_di(%rbp), %rdi jmp .Lperform_syscall
movq IFRAME_si(%rbp), %rsi
movq IFRAME_dx(%rbp), %rdx
movq IFRAME_r10(%rbp), %rcx
movq IFRAME_r8(%rbp), %r8
movq IFRAME_r9(%rbp), %r9
// TODO: pre-syscall tracing/debug
// Call the function and save its return value.
call *SYSCALL_INFO_function(%rax)
movq %rax, IFRAME_ax(%rbp)
// TODO: post-syscall tracing
// Restore the original stack pointer and return.
movq %rbp, %rsp
jmp .Lsyscall_return
.Lbad_syscall_args: .Lbad_syscall_args:
movq $0, THREAD_fault_handler(%r12) movq $0, THREAD_fault_handler(%r12)
-141
View File
@@ -1,141 +0,0 @@
/*
* Copyright 2012, Alex Smith, alex@alex-smith.me.uk.
* Distributed under the terms of the MIT License.
*/
// This file contains stubs for everything that's not been implemented yet on
// x86_64.
#include <cpu.h>
#include <commpage.h>
#include <debug.h>
#include <debugger.h>
#include <elf.h>
#include <elf_priv.h>
#include <real_time_clock.h>
#include <real_time_data.h>
#include <smp.h>
#include <timer.h>
#include <team.h>
#include <thread.h>
#include <vm/vm.h>
#include <vm/VMAddressSpace.h>
#include <boot/kernel_args.h>
#include <arch/debug.h>
#include <arch/vm_translation_map.h>
#include <arch/vm.h>
#include <arch/user_debugger.h>
#include <arch/timer.h>
#include <arch/thread.h>
#include <arch/system_info.h>
#include <arch/smp.h>
#include <arch/real_time_clock.h>
#include <arch/elf.h>
// The software breakpoint instruction (int3).
const uint8 kX86SoftwareBreakpoint[1] = { 0xcc };
void
arch_clear_team_debug_info(struct arch_team_debug_info *info)
{
}
void
arch_destroy_team_debug_info(struct arch_team_debug_info *info)
{
}
void
arch_clear_thread_debug_info(struct arch_thread_debug_info *info)
{
}
void
arch_destroy_thread_debug_info(struct arch_thread_debug_info *info)
{
}
void
arch_update_thread_single_step()
{
}
void
arch_set_debug_cpu_state(const debug_cpu_state *cpuState)
{
}
void
arch_get_debug_cpu_state(debug_cpu_state *cpuState)
{
}
status_t
arch_set_breakpoint(void *address)
{
return B_OK;
}
status_t
arch_clear_breakpoint(void *address)
{
return B_OK;
}
status_t
arch_set_watchpoint(void *address, uint32 type, int32 length)
{
return B_OK;
}
status_t
arch_clear_watchpoint(void *address)
{
return B_OK;
}
bool
arch_has_breakpoints(struct arch_team_debug_info *info)
{
return false;
}
void
x86_init_user_debug()
{
}
status_t
_user_read_kernel_image_symbols(image_id id, struct Elf32_Sym* symbolTable,
int32* _symbolCount, char* stringTable, size_t* _stringTableSize,
addr_t* _imageDelta)
{
return B_ERROR;
}
+1 -2
View File
@@ -24,7 +24,6 @@ if $(TARGET_ARCH) = x86_64 {
cpuid.S cpuid.S
int.cpp int.cpp
interrupts.S interrupts.S
stubs.cpp
signals.cpp signals.cpp
signals_asm.S signals_asm.S
syscalls.cpp syscalls.cpp
@@ -56,7 +55,6 @@ if $(TARGET_ARCH) = x86_64 {
syscalls_asm.S syscalls_asm.S
thread.cpp thread.cpp
arch_user_debugger.cpp
ioapic.cpp ioapic.cpp
irq_routing_table.cpp irq_routing_table.cpp
@@ -88,6 +86,7 @@ local archGenericSources =
arch_system_info.cpp arch_system_info.cpp
arch_thread.cpp arch_thread.cpp
arch_timer.cpp arch_timer.cpp
arch_user_debugger.cpp
arch_vm.cpp arch_vm.cpp
arch_vm_translation_map.cpp arch_vm_translation_map.cpp
apic.cpp apic.cpp
+169 -83
View File
@@ -39,27 +39,27 @@ extern bool gHasSSE;
const uint8 kX86SoftwareBreakpoint[1] = { 0xcc }; const uint8 kX86SoftwareBreakpoint[1] = { 0xcc };
// maps breakpoint slot index to LEN_i LSB number // maps breakpoint slot index to LEN_i LSB number
static const uint32 sDR7Len[4] = { static const size_t sDR7Len[4] = {
X86_DR7_LEN0_LSB, X86_DR7_LEN1_LSB, X86_DR7_LEN2_LSB, X86_DR7_LEN3_LSB X86_DR7_LEN0_LSB, X86_DR7_LEN1_LSB, X86_DR7_LEN2_LSB, X86_DR7_LEN3_LSB
}; };
// maps breakpoint slot index to R/W_i LSB number // maps breakpoint slot index to R/W_i LSB number
static const uint32 sDR7RW[4] = { static const size_t sDR7RW[4] = {
X86_DR7_RW0_LSB, X86_DR7_RW1_LSB, X86_DR7_RW2_LSB, X86_DR7_RW3_LSB X86_DR7_RW0_LSB, X86_DR7_RW1_LSB, X86_DR7_RW2_LSB, X86_DR7_RW3_LSB
}; };
// maps breakpoint slot index to L_i bit number // maps breakpoint slot index to L_i bit number
static const uint32 sDR7L[4] = { static const size_t sDR7L[4] = {
X86_DR7_L0, X86_DR7_L1, X86_DR7_L2, X86_DR7_L3 X86_DR7_L0, X86_DR7_L1, X86_DR7_L2, X86_DR7_L3
}; };
// maps breakpoint slot index to G_i bit number // maps breakpoint slot index to G_i bit number
static const uint32 sDR7G[4] = { static const size_t sDR7G[4] = {
X86_DR7_G0, X86_DR7_G1, X86_DR7_G2, X86_DR7_G3 X86_DR7_G0, X86_DR7_G1, X86_DR7_G2, X86_DR7_G3
}; };
// maps breakpoint slot index to B_i bit number // maps breakpoint slot index to B_i bit number
static const uint32 sDR6B[4] = { static const size_t sDR6B[4] = {
X86_DR6_B0, X86_DR6_B1, X86_DR6_B2, X86_DR6_B3 X86_DR6_B0, X86_DR6_B1, X86_DR6_B2, X86_DR6_B3
}; };
@@ -68,8 +68,78 @@ static const uint32 sDR6B[4] = {
static bool sQEmuSingleStepHack = false; static bool sQEmuSingleStepHack = false;
#ifdef __x86_64__
static void static void
get_iframe_registers(struct iframe *frame, debug_cpu_state *cpuState) get_iframe_registers(const iframe* frame, debug_cpu_state* cpuState)
{
// Get general purpose registers.
cpuState->r15 = frame->r15;
cpuState->r14 = frame->r14;
cpuState->r13 = frame->r13;
cpuState->r12 = frame->r12;
cpuState->r11 = frame->r11;
cpuState->r10 = frame->r10;
cpuState->r9 = frame->r9;
cpuState->r8 = frame->r8;
cpuState->rbp = frame->bp;
cpuState->rsi = frame->si;
cpuState->rdi = frame->di;
cpuState->rdx = frame->dx;
cpuState->rcx = frame->cx;
cpuState->rbx = frame->bx;
cpuState->rax = frame->ax;
cpuState->rip = frame->ip;
cpuState->cs = frame->cs;
cpuState->rflags = frame->flags;
cpuState->rsp = frame->sp;
cpuState->ss = frame->ss;
// Other segment registers are not saved or changed on interrupts, so
// get their value here.
uint16 seg;
__asm__ volatile ("movw %%ds, %0" : "=r" (seg));
cpuState->ds = seg;
__asm__ volatile ("movw %%es, %0" : "=r" (seg));
cpuState->es = seg;
__asm__ volatile ("movw %%fs, %0" : "=r" (seg));
cpuState->fs = seg;
__asm__ volatile ("movw %%gs, %0" : "=r" (seg));
cpuState->gs = seg;
}
static void
set_iframe_registers(iframe* frame, const debug_cpu_state* cpuState)
{
frame->r15 = cpuState->r15;
frame->r14 = cpuState->r14;
frame->r13 = cpuState->r13;
frame->r12 = cpuState->r12;
frame->r11 = cpuState->r11;
frame->r10 = cpuState->r10;
frame->r9 = cpuState->r9;
frame->r8 = cpuState->r8;
frame->bp = cpuState->rbp;
frame->si = cpuState->rsi;
frame->di = cpuState->rdi;
frame->dx = cpuState->rdx;
frame->cx = cpuState->rcx;
frame->bx = cpuState->rbx;
frame->ax = cpuState->rax;
frame->ip = cpuState->rip;
frame->flags = (frame->flags & ~X86_EFLAGS_USER_SETTABLE_FLAGS)
| (cpuState->rflags & X86_EFLAGS_USER_SETTABLE_FLAGS);
frame->sp = cpuState->rsp;
}
#else // __x86_64__
static void
get_iframe_registers(const iframe* frame, debug_cpu_state* cpuState)
{ {
cpuState->gs = frame->gs; cpuState->gs = frame->gs;
cpuState->fs = frame->fs; cpuState->fs = frame->fs;
@@ -93,25 +163,56 @@ get_iframe_registers(struct iframe *frame, debug_cpu_state *cpuState)
} }
static void
set_iframe_registers(iframe* frame, const debug_cpu_state* cpuState)
{
// frame->gs = cpuState->gs;
// frame->fs = cpuState->fs;
// frame->es = cpuState->es;
// frame->ds = cpuState->ds;
frame->di = cpuState->edi;
frame->si = cpuState->esi;
frame->bp = cpuState->ebp;
// frame->esp = cpuState->esp;
frame->bx = cpuState->ebx;
frame->dx = cpuState->edx;
frame->cx = cpuState->ecx;
frame->ax = cpuState->eax;
// frame->vector = cpuState->vector;
// frame->error_code = cpuState->error_code;
frame->ip = cpuState->eip;
// frame->cs = cpuState->cs;
frame->flags = (frame->flags & ~X86_EFLAGS_USER_SETTABLE_FLAGS)
| (cpuState->eflags & X86_EFLAGS_USER_SETTABLE_FLAGS);
frame->user_sp = cpuState->user_esp;
// frame->user_ss = cpuState->user_ss;
}
#endif // __x86_64__
static inline void static inline void
install_breakpoints(const arch_team_debug_info &teamInfo) install_breakpoints(const arch_team_debug_info& teamInfo)
{ {
// set breakpoints // set breakpoints
asm("movl %0, %%dr0" : : "r"(teamInfo.breakpoints[0].address)); asm("mov %0, %%dr0" : : "r"(teamInfo.breakpoints[0].address));
asm("movl %0, %%dr1" : : "r"(teamInfo.breakpoints[1].address)); asm("mov %0, %%dr1" : : "r"(teamInfo.breakpoints[1].address));
asm("movl %0, %%dr2" : : "r"(teamInfo.breakpoints[2].address)); asm("mov %0, %%dr2" : : "r"(teamInfo.breakpoints[2].address));
// asm("movl %0, %%dr3" : : "r"(teamInfo.breakpoints[3].address)); #ifdef __x86_64__
// DR3 is used to hold the current Thread*. asm("mov %0, %%dr3" : : "r"(teamInfo.breakpoints[3].address));
// DR3 is used to hold the current Thread* on 32.
#endif
// enable breakpoints // enable breakpoints
asm("movl %0, %%dr7" : : "r"(teamInfo.dr7)); asm("mov %0, %%dr7" : : "r"(teamInfo.dr7));
} }
static inline void static inline void
disable_breakpoints() disable_breakpoints()
{ {
asm("movl %0, %%dr7" : : "r"(X86_BREAKPOINTS_DISABLED_DR7)); asm("mov %0, %%dr7" : : "r"((size_t)X86_BREAKPOINTS_DISABLED_DR7));
} }
@@ -119,8 +220,8 @@ disable_breakpoints()
Interrupts must be disabled and the team debug info lock be held. Interrupts must be disabled and the team debug info lock be held.
*/ */
static inline status_t static inline status_t
set_breakpoint(arch_team_debug_info &info, void *address, uint32 type, set_breakpoint(arch_team_debug_info& info, void* address, size_t type,
uint32 length, bool setGlobalFlag) size_t length, bool setGlobalFlag)
{ {
// check, if there is already a breakpoint at that address // check, if there is already a breakpoint at that address
bool alreadySet = false; bool alreadySet = false;
@@ -169,7 +270,7 @@ set_breakpoint(arch_team_debug_info &info, void *address, uint32 type,
Interrupts must be disabled and the team debug info lock be held. Interrupts must be disabled and the team debug info lock be held.
*/ */
static inline status_t static inline status_t
clear_breakpoint(arch_team_debug_info &info, void *address, bool watchpoint) clear_breakpoint(arch_team_debug_info& info, void* address, bool watchpoint)
{ {
// find the breakpoint // find the breakpoint
int32 slot = -1; int32 slot = -1;
@@ -202,12 +303,12 @@ clear_breakpoint(arch_team_debug_info &info, void *address, bool watchpoint)
static status_t static status_t
set_breakpoint(void *address, uint32 type, uint32 length) set_breakpoint(void* address, size_t type, size_t length)
{ {
if (!address) if (!address)
return B_BAD_VALUE; return B_BAD_VALUE;
Thread *thread = thread_get_current_thread(); Thread* thread = thread_get_current_thread();
cpu_status state = disable_interrupts(); cpu_status state = disable_interrupts();
GRAB_TEAM_DEBUG_INFO_LOCK(thread->team->debug_info); GRAB_TEAM_DEBUG_INFO_LOCK(thread->team->debug_info);
@@ -223,12 +324,12 @@ set_breakpoint(void *address, uint32 type, uint32 length)
static status_t static status_t
clear_breakpoint(void *address, bool watchpoint) clear_breakpoint(void* address, bool watchpoint)
{ {
if (!address) if (!address)
return B_BAD_VALUE; return B_BAD_VALUE;
Thread *thread = thread_get_current_thread(); Thread* thread = thread_get_current_thread();
cpu_status state = disable_interrupts(); cpu_status state = disable_interrupts();
GRAB_TEAM_DEBUG_INFO_LOCK(thread->team->debug_info); GRAB_TEAM_DEBUG_INFO_LOCK(thread->team->debug_info);
@@ -260,7 +361,7 @@ install_breakpoints_per_cpu(void* /*cookie*/, int cpu)
static status_t static status_t
set_kernel_breakpoint(void *address, uint32 type, uint32 length) set_kernel_breakpoint(void* address, size_t type, size_t length)
{ {
if (!address) if (!address)
return B_BAD_VALUE; return B_BAD_VALUE;
@@ -284,7 +385,7 @@ set_kernel_breakpoint(void *address, uint32 type, uint32 length)
static status_t static status_t
clear_kernel_breakpoint(void *address, bool watchpoint) clear_kernel_breakpoint(void* address, bool watchpoint)
{ {
if (!address) if (!address)
return B_BAD_VALUE; return B_BAD_VALUE;
@@ -311,7 +412,7 @@ clear_kernel_breakpoint(void *address, bool watchpoint)
static inline status_t static inline status_t
check_watch_point_parameters(void* address, uint32 type, int32 length, check_watch_point_parameters(void* address, uint32 type, int32 length,
uint32& archType, uint32& archLength) size_t& archType, size_t& archLength)
{ {
// check type // check type
switch (type) { switch (type) {
@@ -333,12 +434,12 @@ check_watch_point_parameters(void* address, uint32 type, int32 length,
archLength = X86_BREAKPOINT_LENGTH_1; archLength = X86_BREAKPOINT_LENGTH_1;
break; break;
case 2: case 2:
if ((uint32)address & 0x1) if ((addr_t)address & 0x1)
return B_BAD_WATCHPOINT_ALIGNMENT; return B_BAD_WATCHPOINT_ALIGNMENT;
archLength = X86_BREAKPOINT_LENGTH_2; archLength = X86_BREAKPOINT_LENGTH_2;
break; break;
case 4: case 4:
if ((uint32)address & 0x3) if ((addr_t)address & 0x3)
return B_BAD_WATCHPOINT_ALIGNMENT; return B_BAD_WATCHPOINT_ALIGNMENT;
archLength = X86_BREAKPOINT_LENGTH_4; archLength = X86_BREAKPOINT_LENGTH_4;
break; break;
@@ -352,6 +453,7 @@ check_watch_point_parameters(void* address, uint32 type, int32 length,
// #pragma mark - kernel debugger commands // #pragma mark - kernel debugger commands
#if KERNEL_BREAKPOINTS #if KERNEL_BREAKPOINTS
static int static int
@@ -361,7 +463,7 @@ debugger_breakpoints(int argc, char** argv)
arch_team_debug_info& info = kernelTeam->debug_info.arch_info; arch_team_debug_info& info = kernelTeam->debug_info.arch_info;
for (int32 i = 0; i < X86_BREAKPOINT_COUNT; i++) { for (int32 i = 0; i < X86_BREAKPOINT_COUNT; i++) {
kprintf("breakpoint[%ld] ", i); kprintf("breakpoint[%" B_PRId32 "] ", i);
if (info.breakpoints[i].address != NULL) { if (info.breakpoints[i].address != NULL) {
kprintf("%p ", info.breakpoints[i].address); kprintf("%p ", info.breakpoints[i].address);
@@ -491,7 +593,7 @@ debugger_watchpoint(int argc, char** argv)
uint32 type = readWrite ? B_DATA_READ_WRITE_WATCHPOINT uint32 type = readWrite ? B_DATA_READ_WRITE_WATCHPOINT
: B_DATA_WRITE_WATCHPOINT; : B_DATA_WRITE_WATCHPOINT;
uint32 archType, archLength; size_t archType, archLength;
error = check_watch_point_parameters((void*)address, type, length, error = check_watch_point_parameters((void*)address, type, length,
archType, archLength); archType, archLength);
@@ -516,7 +618,7 @@ debugger_single_step(int argc, char** argv)
// TODO: Since we need an iframe, this doesn't work when KDL wasn't entered // TODO: Since we need an iframe, this doesn't work when KDL wasn't entered
// via an exception. // via an exception.
struct iframe* frame = x86_get_current_iframe(); iframe* frame = x86_get_current_iframe();
if (frame == NULL) { if (frame == NULL) {
kprintf("Failed to get the current iframe!\n"); kprintf("Failed to get the current iframe!\n");
return 0; return 0;
@@ -535,7 +637,7 @@ debugger_single_step(int argc, char** argv)
void void
arch_clear_team_debug_info(struct arch_team_debug_info *info) arch_clear_team_debug_info(arch_team_debug_info* info)
{ {
for (int32 i = 0; i < X86_BREAKPOINT_COUNT; i++) for (int32 i = 0; i < X86_BREAKPOINT_COUNT; i++)
info->breakpoints[i].address = NULL; info->breakpoints[i].address = NULL;
@@ -545,21 +647,21 @@ arch_clear_team_debug_info(struct arch_team_debug_info *info)
void void
arch_destroy_team_debug_info(struct arch_team_debug_info *info) arch_destroy_team_debug_info(arch_team_debug_info* info)
{ {
arch_clear_team_debug_info(info); arch_clear_team_debug_info(info);
} }
void void
arch_clear_thread_debug_info(struct arch_thread_debug_info *info) arch_clear_thread_debug_info(arch_thread_debug_info* info)
{ {
info->flags = 0; info->flags = 0;
} }
void void
arch_destroy_thread_debug_info(struct arch_thread_debug_info *info) arch_destroy_thread_debug_info(arch_thread_debug_info* info)
{ {
arch_clear_thread_debug_info(info); arch_clear_thread_debug_info(info);
} }
@@ -568,7 +670,7 @@ arch_destroy_thread_debug_info(struct arch_thread_debug_info *info)
void void
arch_update_thread_single_step() arch_update_thread_single_step()
{ {
if (struct iframe* frame = x86_get_user_iframe()) { if (iframe* frame = x86_get_user_iframe()) {
Thread* thread = thread_get_current_thread(); Thread* thread = thread_get_current_thread();
// set/clear TF in EFLAGS depending on whether single stepping is // set/clear TF in EFLAGS depending on whether single stepping is
@@ -582,9 +684,9 @@ arch_update_thread_single_step()
void void
arch_set_debug_cpu_state(const debug_cpu_state *cpuState) arch_set_debug_cpu_state(const debug_cpu_state* cpuState)
{ {
if (struct iframe *frame = x86_get_user_iframe()) { if (iframe* frame = x86_get_user_iframe()) {
// For the floating point state to be correct the calling function must // For the floating point state to be correct the calling function must
// not use these registers (not even indirectly). // not use these registers (not even indirectly).
if (gHasSSE) { if (gHasSSE) {
@@ -597,39 +699,21 @@ arch_set_debug_cpu_state(const debug_cpu_state *cpuState)
memcpy(thread->arch_info.fpu_state, &cpuState->extended_registers, memcpy(thread->arch_info.fpu_state, &cpuState->extended_registers,
sizeof(cpuState->extended_registers)); sizeof(cpuState->extended_registers));
x86_fxrstor(thread->arch_info.fpu_state); x86_fxrstor(thread->arch_info.fpu_state);
#ifndef __x86_64__
} else { } else {
// TODO: Implement! We need to convert the format first. // TODO: Implement! We need to convert the format first.
// x86_frstor(&cpuState->extended_registers); // x86_frstor(&cpuState->extended_registers);
#endif
} }
set_iframe_registers(frame, cpuState);
// frame->gs = cpuState->gs;
// frame->fs = cpuState->fs;
// frame->es = cpuState->es;
// frame->ds = cpuState->ds;
frame->di = cpuState->edi;
frame->si = cpuState->esi;
frame->bp = cpuState->ebp;
// frame->esp = cpuState->esp;
frame->bx = cpuState->ebx;
frame->dx = cpuState->edx;
frame->cx = cpuState->ecx;
frame->ax = cpuState->eax;
// frame->vector = cpuState->vector;
// frame->error_code = cpuState->error_code;
frame->ip = cpuState->eip;
// frame->cs = cpuState->cs;
frame->flags = (frame->flags & ~X86_EFLAGS_USER_SETTABLE_FLAGS)
| (cpuState->eflags & X86_EFLAGS_USER_SETTABLE_FLAGS);
frame->user_sp = cpuState->user_esp;
// frame->user_ss = cpuState->user_ss;
} }
} }
void void
arch_get_debug_cpu_state(debug_cpu_state *cpuState) arch_get_debug_cpu_state(debug_cpu_state* cpuState)
{ {
if (struct iframe *frame = x86_get_user_iframe()) { if (iframe* frame = x86_get_user_iframe()) {
// For the floating point state to be correct the calling function must // For the floating point state to be correct the calling function must
// not use these registers (not even indirectly). // not use these registers (not even indirectly).
if (gHasSSE) { if (gHasSSE) {
@@ -642,12 +726,14 @@ arch_get_debug_cpu_state(debug_cpu_state *cpuState)
// unlike fnsave, fxsave doesn't reinit the FPU state // unlike fnsave, fxsave doesn't reinit the FPU state
memcpy(&cpuState->extended_registers, thread->arch_info.fpu_state, memcpy(&cpuState->extended_registers, thread->arch_info.fpu_state,
sizeof(cpuState->extended_registers)); sizeof(cpuState->extended_registers));
#ifndef __x86_64__
} else { } else {
x86_fnsave(&cpuState->extended_registers); x86_fnsave(&cpuState->extended_registers);
x86_frstor(&cpuState->extended_registers); x86_frstor(&cpuState->extended_registers);
// fnsave reinits the FPU state after saving, so we need to // fnsave reinits the FPU state after saving, so we need to
// load it again // load it again
// TODO: Convert to fxsave format! // TODO: Convert to fxsave format!
#endif
} }
get_iframe_registers(frame, cpuState); get_iframe_registers(frame, cpuState);
} }
@@ -655,7 +741,7 @@ arch_get_debug_cpu_state(debug_cpu_state *cpuState)
status_t status_t
arch_set_breakpoint(void *address) arch_set_breakpoint(void* address)
{ {
return set_breakpoint(address, X86_INSTRUCTION_BREAKPOINT, return set_breakpoint(address, X86_INSTRUCTION_BREAKPOINT,
X86_BREAKPOINT_LENGTH_1); X86_BREAKPOINT_LENGTH_1);
@@ -663,16 +749,16 @@ arch_set_breakpoint(void *address)
status_t status_t
arch_clear_breakpoint(void *address) arch_clear_breakpoint(void* address)
{ {
return clear_breakpoint(address, false); return clear_breakpoint(address, false);
} }
status_t status_t
arch_set_watchpoint(void *address, uint32 type, int32 length) arch_set_watchpoint(void* address, uint32 type, int32 length)
{ {
uint32 archType, archLength; size_t archType, archLength;
status_t error = check_watch_point_parameters(address, type, length, status_t error = check_watch_point_parameters(address, type, length,
archType, archLength); archType, archLength);
if (error != B_OK) if (error != B_OK)
@@ -683,14 +769,14 @@ arch_set_watchpoint(void *address, uint32 type, int32 length)
status_t status_t
arch_clear_watchpoint(void *address) arch_clear_watchpoint(void* address)
{ {
return clear_breakpoint(address, true); return clear_breakpoint(address, true);
} }
bool bool
arch_has_breakpoints(struct arch_team_debug_info *info) arch_has_breakpoints(arch_team_debug_info* info)
{ {
// Reading info->dr7 is atomically, so we don't need to lock. The caller // Reading info->dr7 is atomically, so we don't need to lock. The caller
// has to ensure, that the info doesn't go away. // has to ensure, that the info doesn't go away.
@@ -701,7 +787,7 @@ arch_has_breakpoints(struct arch_team_debug_info *info)
#if KERNEL_BREAKPOINTS #if KERNEL_BREAKPOINTS
status_t status_t
arch_set_kernel_breakpoint(void *address) arch_set_kernel_breakpoint(void* address)
{ {
status_t error = set_kernel_breakpoint(address, X86_INSTRUCTION_BREAKPOINT, status_t error = set_kernel_breakpoint(address, X86_INSTRUCTION_BREAKPOINT,
X86_BREAKPOINT_LENGTH_1); X86_BREAKPOINT_LENGTH_1);
@@ -716,7 +802,7 @@ arch_set_kernel_breakpoint(void *address)
status_t status_t
arch_clear_kernel_breakpoint(void *address) arch_clear_kernel_breakpoint(void* address)
{ {
status_t error = clear_kernel_breakpoint(address, false); status_t error = clear_kernel_breakpoint(address, false);
@@ -730,9 +816,9 @@ arch_clear_kernel_breakpoint(void *address)
status_t status_t
arch_set_kernel_watchpoint(void *address, uint32 type, int32 length) arch_set_kernel_watchpoint(void* address, uint32 type, int32 length)
{ {
uint32 archType, archLength; size_t archType, archLength;
status_t error = check_watch_point_parameters(address, type, length, status_t error = check_watch_point_parameters(address, type, length,
archType, archLength); archType, archLength);
@@ -749,7 +835,7 @@ arch_set_kernel_watchpoint(void *address, uint32 type, int32 length)
status_t status_t
arch_clear_kernel_watchpoint(void *address) arch_clear_kernel_watchpoint(void* address)
{ {
status_t error = clear_kernel_breakpoint(address, true); status_t error = clear_kernel_breakpoint(address, true);
@@ -771,9 +857,9 @@ arch_clear_kernel_watchpoint(void *address)
* Interrupts are disabled. \a frame is unused, i.e. can be \c NULL. * Interrupts are disabled. \a frame is unused, i.e. can be \c NULL.
*/ */
void void
x86_init_user_debug_at_kernel_exit(struct iframe *frame) x86_init_user_debug_at_kernel_exit(iframe* frame)
{ {
Thread *thread = thread_get_current_thread(); Thread* thread = thread_get_current_thread();
if (!(thread->flags & THREAD_FLAGS_BREAKPOINTS_DEFINED)) if (!(thread->flags & THREAD_FLAGS_BREAKPOINTS_DEFINED))
return; return;
@@ -800,14 +886,14 @@ x86_init_user_debug_at_kernel_exit(struct iframe *frame)
void void
x86_exit_user_debug_at_kernel_entry() x86_exit_user_debug_at_kernel_entry()
{ {
Thread *thread = thread_get_current_thread(); Thread* thread = thread_get_current_thread();
// We need to save the current values of dr6 and dr7 in the CPU structure, // We need to save the current values of dr6 and dr7 in the CPU structure,
// since in case of a debug exception we might overwrite them before // since in case of a debug exception we might overwrite them before
// x86_handle_debug_exception() is called. Debug exceptions occur when // x86_handle_debug_exception() is called. Debug exceptions occur when
// hitting a hardware break/watchpoint or when single-stepping. // hitting a hardware break/watchpoint or when single-stepping.
asm("movl %%dr6, %0" : "=r"(thread->cpu->arch.dr6)); asm("mov %%dr6, %0" : "=r"(thread->cpu->arch.dr6));
asm("movl %%dr7, %0" : "=r"(thread->cpu->arch.dr7)); asm("mov %%dr7, %0" : "=r"(thread->cpu->arch.dr7));
// The remainder needs only be done, when user breakpoints are installed. // The remainder needs only be done, when user breakpoints are installed.
if (!(thread->flags & THREAD_FLAGS_BREAKPOINTS_INSTALLED)) if (!(thread->flags & THREAD_FLAGS_BREAKPOINTS_INSTALLED))
@@ -833,7 +919,7 @@ x86_exit_user_debug_at_kernel_entry()
* Interrupts are disabled and will possibly be enabled by the function. * Interrupts are disabled and will possibly be enabled by the function.
*/ */
void void
x86_handle_debug_exception(struct iframe *frame) x86_handle_debug_exception(iframe* frame)
{ {
Thread* thread = thread_get_current_thread(); Thread* thread = thread_get_current_thread();
@@ -842,14 +928,14 @@ x86_handle_debug_exception(struct iframe *frame)
// x86_exit_user_debug_at_kernel_entry() has already been invoked and dr6 // x86_exit_user_debug_at_kernel_entry() has already been invoked and dr6
// and dr7 are stored in the cpu info. Otherwise we need to fetch the // and dr7 are stored in the cpu info. Otherwise we need to fetch the
// current values from the registers. // current values from the registers.
uint32 dr6; size_t dr6;
uint32 dr7; size_t dr7;
if (IFRAME_IS_USER(frame)) { if (IFRAME_IS_USER(frame)) {
dr6 = thread->cpu->arch.dr6; dr6 = thread->cpu->arch.dr6;
dr7 = thread->cpu->arch.dr7; dr7 = thread->cpu->arch.dr7;
} else { } else {
asm("movl %%dr6, %0" : "=r"(dr6)); asm("mov %%dr6, %0" : "=r"(dr6));
asm("movl %%dr7, %0" : "=r"(dr7)); asm("mov %%dr7, %0" : "=r"(dr7));
} }
TRACE(("x86_handle_debug_exception(): DR6: %lx, DR7: %lx\n", dr6, dr7)); TRACE(("x86_handle_debug_exception(): DR6: %lx, DR7: %lx\n", dr6, dr7));
@@ -862,7 +948,7 @@ x86_handle_debug_exception(struct iframe *frame)
bool watchpoint = true; bool watchpoint = true;
for (int32 i = 0; i < X86_BREAKPOINT_COUNT; i++) { for (int32 i = 0; i < X86_BREAKPOINT_COUNT; i++) {
if (dr6 & (1 << sDR6B[i])) { if (dr6 & (1 << sDR6B[i])) {
uint32 type = (dr7 >> sDR7RW[i]) & 0x3; size_t type = (dr7 >> sDR7RW[i]) & 0x3;
if (type == X86_INSTRUCTION_BREAKPOINT) if (type == X86_INSTRUCTION_BREAKPOINT)
watchpoint = false; watchpoint = false;
} }
@@ -972,7 +1058,7 @@ x86_handle_debug_exception(struct iframe *frame)
* Interrupts are disabled and will possibly be enabled by the function. * Interrupts are disabled and will possibly be enabled by the function.
*/ */
void void
x86_handle_breakpoint_exception(struct iframe *frame) x86_handle_breakpoint_exception(iframe* frame)
{ {
TRACE(("x86_handle_breakpoint_exception()\n")); TRACE(("x86_handle_breakpoint_exception()\n"));
@@ -994,7 +1080,7 @@ void
x86_init_user_debug() x86_init_user_debug()
{ {
// get debug settings // get debug settings
if (void *handle = load_driver_settings("kernel")) { if (void* handle = load_driver_settings("kernel")) {
sQEmuSingleStepHack = get_driver_boolean_parameter(handle, sQEmuSingleStepHack = get_driver_boolean_parameter(handle,
"qemu_single_step_hack", false, false);; "qemu_single_step_hack", false, false);;
+102 -89
View File
@@ -77,8 +77,9 @@ static status_t
debugger_write(port_id port, int32 code, const void *buffer, size_t bufferSize, debugger_write(port_id port, int32 code, const void *buffer, size_t bufferSize,
bool dontWait) bool dontWait)
{ {
TRACE(("debugger_write(): thread: %ld, team %ld, port: %ld, code: %lx, message: %p, " TRACE(("debugger_write(): thread: %" B_PRId32 ", team %" B_PRId32 ", "
"size: %lu, dontWait: %d\n", thread_get_current_thread()->id, "port: %" B_PRId32 ", code: %" B_PRIx32 ", message: %p, size: %lu, "
"dontWait: %d\n", thread_get_current_thread()->id,
thread_get_current_thread()->team->id, port, code, buffer, bufferSize, thread_get_current_thread()->team->id, port, code, buffer, bufferSize,
dontWait)); dontWait));
@@ -94,7 +95,7 @@ debugger_write(port_id port, int32 code, const void *buffer, size_t bufferSize,
error = acquire_sem_etc(writeLock, 1, error = acquire_sem_etc(writeLock, 1,
dontWait ? (uint32)B_RELATIVE_TIMEOUT : (uint32)B_KILL_CAN_INTERRUPT, 0); dontWait ? (uint32)B_RELATIVE_TIMEOUT : (uint32)B_KILL_CAN_INTERRUPT, 0);
if (error != B_OK) { if (error != B_OK) {
TRACE(("debugger_write() done1: %lx\n", error)); TRACE(("debugger_write() done1: %" B_PRIx32 "\n", error));
return error; return error;
} }
@@ -119,7 +120,7 @@ debugger_write(port_id port, int32 code, const void *buffer, size_t bufferSize,
// release the write lock // release the write lock
release_sem(writeLock); release_sem(writeLock);
TRACE(("debugger_write() done: %lx\n", error)); TRACE(("debugger_write() done: %" B_PRIx32 "\n", error));
return error; return error;
} }
@@ -529,8 +530,9 @@ thread_hit_debug_event_internal(debug_debugger_message event,
restart = false; restart = false;
Thread *thread = thread_get_current_thread(); Thread *thread = thread_get_current_thread();
TRACE(("thread_hit_debug_event(): thread: %ld, event: %lu, message: %p, " TRACE(("thread_hit_debug_event(): thread: %" B_PRId32 ", event: %" B_PRIu32
"size: %ld\n", thread->id, (uint32)event, message, size)); ", message: %p, size: %" B_PRId32 "\n", thread->id, (uint32)event,
message, size));
// check, if there's a debug port already // check, if there's a debug port already
bool setPort = !(atomic_get(&thread->debug_info.flags) bool setPort = !(atomic_get(&thread->debug_info.flags)
@@ -567,8 +569,8 @@ thread_hit_debug_event_internal(debug_debugger_message event,
= (thread->team->debug_info.flags & B_TEAM_DEBUG_DEBUGGER_INSTALLED); = (thread->team->debug_info.flags & B_TEAM_DEBUG_DEBUGGER_INSTALLED);
if (thread->id == thread->team->debug_info.nub_thread) { if (thread->id == thread->team->debug_info.nub_thread) {
// Ugh, we're the nub thread. We shouldn't be here. // Ugh, we're the nub thread. We shouldn't be here.
TRACE(("thread_hit_debug_event(): Misdirected nub thread: %ld\n", TRACE(("thread_hit_debug_event(): Misdirected nub thread: %" B_PRId32
thread->id)); "\n", thread->id));
error = B_ERROR; error = B_ERROR;
} else if (debuggerInstalled || !requireDebugger) { } else if (debuggerInstalled || !requireDebugger) {
@@ -614,8 +616,8 @@ thread_hit_debug_event_internal(debug_debugger_message event,
delete_port(deletePort); delete_port(deletePort);
if (error != B_OK) { if (error != B_OK) {
TRACE(("thread_hit_debug_event() error: thread: %ld, error: %lx\n", TRACE(("thread_hit_debug_event() error: thread: %" B_PRId32 ", error: "
thread->id, error)); "%" B_PRIx32 "\n", thread->id, error));
return error; return error;
} }
@@ -627,8 +629,9 @@ thread_hit_debug_event_internal(debug_debugger_message event,
origin->team = thread->team->id; origin->team = thread->team->id;
origin->nub_port = nubPort; origin->nub_port = nubPort;
TRACE(("thread_hit_debug_event(): thread: %ld, sending message to " TRACE(("thread_hit_debug_event(): thread: %" B_PRId32 ", sending "
"debugger port %ld\n", thread->id, debuggerPort)); "message to debugger port %" B_PRId32 "\n", thread->id,
debuggerPort));
error = debugger_write(debuggerPort, event, message, size, false); error = debugger_write(debuggerPort, event, message, size, false);
} }
@@ -648,15 +651,15 @@ thread_hit_debug_event_internal(debug_debugger_message event,
if (commandMessageSize < 0) { if (commandMessageSize < 0) {
error = commandMessageSize; error = commandMessageSize;
TRACE(("thread_hit_debug_event(): thread: %ld, failed " TRACE(("thread_hit_debug_event(): thread: %" B_PRId32 ", failed "
"to receive message from port %ld: %lx\n", "to receive message from port %" B_PRId32 ": %" B_PRIx32 "\n",
thread->id, port, error)); thread->id, port, error));
break; break;
} }
switch (command) { switch (command) {
case B_DEBUGGED_THREAD_MESSAGE_CONTINUE: case B_DEBUGGED_THREAD_MESSAGE_CONTINUE:
TRACE(("thread_hit_debug_event(): thread: %ld: " TRACE(("thread_hit_debug_event(): thread: %" B_PRId32 ": "
"B_DEBUGGED_THREAD_MESSAGE_CONTINUE\n", "B_DEBUGGED_THREAD_MESSAGE_CONTINUE\n",
thread->id)); thread->id));
result = commandMessage.continue_thread.handle_event; result = commandMessage.continue_thread.handle_event;
@@ -667,7 +670,7 @@ thread_hit_debug_event_internal(debug_debugger_message event,
case B_DEBUGGED_THREAD_SET_CPU_STATE: case B_DEBUGGED_THREAD_SET_CPU_STATE:
{ {
TRACE(("thread_hit_debug_event(): thread: %ld: " TRACE(("thread_hit_debug_event(): thread: %" B_PRId32 ": "
"B_DEBUGGED_THREAD_SET_CPU_STATE\n", "B_DEBUGGED_THREAD_SET_CPU_STATE\n",
thread->id)); thread->id));
arch_set_debug_cpu_state( arch_set_debug_cpu_state(
@@ -720,9 +723,9 @@ thread_hit_debug_event_internal(debug_debugger_message event,
} }
} }
} else { } else {
TRACE(("thread_hit_debug_event(): thread: %ld, failed to send " TRACE(("thread_hit_debug_event(): thread: %" B_PRId32 ", failed to send "
"message to debugger port %ld: %lx\n", thread->id, "message to debugger port %" B_PRId32 ": %" B_PRIx32 "\n",
debuggerPort, error)); thread->id, debuggerPort, error));
} }
// update the thread debug info // update the thread debug info
@@ -993,8 +996,8 @@ void
user_debug_team_deleted(team_id teamID, port_id debuggerPort) user_debug_team_deleted(team_id teamID, port_id debuggerPort)
{ {
if (debuggerPort >= 0) { if (debuggerPort >= 0) {
TRACE(("user_debug_team_deleted(team: %ld, debugger port: %ld)\n", TRACE(("user_debug_team_deleted(team: %" B_PRId32 ", debugger port: "
teamID, debuggerPort)); "%" B_PRId32 ")\n", teamID, debuggerPort));
debug_team_deleted message; debug_team_deleted message;
message.origin.thread = -1; message.origin.thread = -1;
@@ -1541,7 +1544,8 @@ broadcast_debugged_thread_message(Thread *nubThread, int32 code,
code, message, size); code, message, size);
if (error != B_OK) { if (error != B_OK) {
TRACE(("broadcast_debugged_thread_message(): Failed to send " TRACE(("broadcast_debugged_thread_message(): Failed to send "
"message to thread %ld: %lx\n", thread->id, error)); "message to thread %" B_PRId32 ": %" B_PRIx32 "\n",
thread->id, error));
} }
} }
} }
@@ -1551,8 +1555,8 @@ broadcast_debugged_thread_message(Thread *nubThread, int32 code,
static void static void
nub_thread_cleanup(Thread *nubThread) nub_thread_cleanup(Thread *nubThread)
{ {
TRACE(("nub_thread_cleanup(%ld): debugger port: %ld\n", nubThread->id, TRACE(("nub_thread_cleanup(%" B_PRId32 "): debugger port: %" B_PRId32 "\n",
nubThread->team->debug_info.debugger_port)); nubThread->id, nubThread->team->debug_info.debugger_port));
ConditionVariable debugChangeCondition; ConditionVariable debugChangeCondition;
prepare_debugger_change(nubThread->team, debugChangeCondition); prepare_debugger_change(nubThread->team, debugChangeCondition);
@@ -1654,8 +1658,8 @@ debug_nub_thread(void *)
RELEASE_TEAM_DEBUG_INFO_LOCK(nubThread->team->debug_info); RELEASE_TEAM_DEBUG_INFO_LOCK(nubThread->team->debug_info);
restore_interrupts(state); restore_interrupts(state);
TRACE(("debug_nub_thread() thread: %ld, team %ld, nub port: %ld\n", TRACE(("debug_nub_thread() thread: %" B_PRId32 ", team %" B_PRId32 ", nub "
nubThread->id, nubThread->team->id, port)); "port: %" B_PRId32 "\n", nubThread->id, nubThread->team->id, port));
// notify all threads that a debugger has been installed // notify all threads that a debugger has been installed
broadcast_debugged_thread_message(nubThread, broadcast_debugged_thread_message(nubThread,
@@ -1674,8 +1678,8 @@ debug_nub_thread(void *)
// thread, we need to update that. // thread, we need to update that.
nub_thread_cleanup(nubThread); nub_thread_cleanup(nubThread);
TRACE(("nub thread %ld: terminating: %lx\n", nubThread->id, TRACE(("nub thread %" B_PRId32 ": terminating: %lx\n",
messageSize)); nubThread->id, messageSize));
return messageSize; return messageSize;
} }
@@ -1719,10 +1723,10 @@ debug_nub_thread(void *)
} }
reply.read_memory.error = result; reply.read_memory.error = result;
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_READ_MEMORY: " TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_READ_MEMORY: "
"reply port: %ld, address: %p, size: %ld, result: %lx, " "reply port: %" B_PRId32 ", address: %p, size: %" B_PRId32
"read: %ld\n", nubThread->id, replyPort, address, size, ", result: %" B_PRIx32 ", read: %ld\n", nubThread->id,
result, bytesRead)); replyPort, address, size, result, bytesRead));
// send only as much data as necessary // send only as much data as necessary
reply.read_memory.size = bytesRead; reply.read_memory.size = bytesRead;
@@ -1755,10 +1759,10 @@ debug_nub_thread(void *)
} }
reply.write_memory.error = result; reply.write_memory.error = result;
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_WRITE_MEMORY: " TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_WRITE_MEMORY: "
"reply port: %ld, address: %p, size: %ld, result: %lx, " "reply port: %" B_PRId32 ", address: %p, size: %" B_PRId32
"written: %ld\n", nubThread->id, replyPort, address, size, ", result: %" B_PRIx32 ", written: %ld\n", nubThread->id,
result, bytesWritten)); replyPort, address, size, result, bytesWritten));
reply.write_memory.size = bytesWritten; reply.write_memory.size = bytesWritten;
sendReply = true; sendReply = true;
@@ -1772,8 +1776,8 @@ debug_nub_thread(void *)
int32 flags = message.set_team_flags.flags int32 flags = message.set_team_flags.flags
& B_TEAM_DEBUG_USER_FLAG_MASK; & B_TEAM_DEBUG_USER_FLAG_MASK;
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_SET_TEAM_FLAGS: " TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_SET_TEAM_FLAGS"
"flags: %lx\n", nubThread->id, flags)); ": flags: %" B_PRIx32 "\n", nubThread->id, flags));
Team *team = thread_get_current_thread()->team; Team *team = thread_get_current_thread()->team;
@@ -1797,9 +1801,9 @@ debug_nub_thread(void *)
int32 flags = message.set_thread_flags.flags int32 flags = message.set_thread_flags.flags
& B_THREAD_DEBUG_USER_FLAG_MASK; & B_THREAD_DEBUG_USER_FLAG_MASK;
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_SET_THREAD_FLAGS: " TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_SET_THREAD_FLAGS"
"thread: %ld, flags: %lx\n", nubThread->id, threadID, ": thread: %" B_PRId32 ", flags: %" B_PRIx32 "\n",
flags)); nubThread->id, threadID, flags));
// set the flags // set the flags
Thread* thread = Thread::GetAndLock(threadID); Thread* thread = Thread::GetAndLock(threadID);
@@ -1831,9 +1835,10 @@ debug_nub_thread(void *)
handleEvent = message.continue_thread.handle_event; handleEvent = message.continue_thread.handle_event;
singleStep = message.continue_thread.single_step; singleStep = message.continue_thread.single_step;
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_CONTINUE_THREAD: " TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_CONTINUE_THREAD"
"thread: %ld, handle event: %lu, single step: %d\n", ": thread: %" B_PRId32 ", handle event: %" B_PRIu32 ", "
nubThread->id, threadID, handleEvent, singleStep)); "single step: %d\n", nubThread->id, threadID, handleEvent,
singleStep));
// find the thread and get its debug port // find the thread and get its debug port
port_id threadDebugPort = -1; port_id threadDebugPort = -1;
@@ -1861,8 +1866,8 @@ debug_nub_thread(void *)
const debug_cpu_state &cpuState const debug_cpu_state &cpuState
= message.set_cpu_state.cpu_state; = message.set_cpu_state.cpu_state;
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_SET_CPU_STATE: " TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_SET_CPU_STATE"
"thread: %ld\n", nubThread->id, threadID)); ": thread: %" B_PRId32 "\n", nubThread->id, threadID));
// find the thread and get its debug port // find the thread and get its debug port
port_id threadDebugPort = -1; port_id threadDebugPort = -1;
@@ -1888,8 +1893,8 @@ debug_nub_thread(void *)
thread_id threadID = message.get_cpu_state.thread; thread_id threadID = message.get_cpu_state.thread;
replyPort = message.get_cpu_state.reply_port; replyPort = message.get_cpu_state.reply_port;
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_GET_CPU_STATE: " TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_GET_CPU_STATE"
"thread: %ld\n", nubThread->id, threadID)); ": thread: %" B_PRId32 "\n", nubThread->id, threadID));
// find the thread and get its debug port // find the thread and get its debug port
port_id threadDebugPort = -1; port_id threadDebugPort = -1;
@@ -1921,8 +1926,8 @@ debug_nub_thread(void *)
replyPort = message.set_breakpoint.reply_port; replyPort = message.set_breakpoint.reply_port;
void *address = message.set_breakpoint.address; void *address = message.set_breakpoint.address;
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_SET_BREAKPOINT: " TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_SET_BREAKPOINT"
"address: %p\n", nubThread->id, address)); ": address: %p\n", nubThread->id, address));
// check the address // check the address
status_t result = B_OK; status_t result = B_OK;
@@ -1951,8 +1956,8 @@ debug_nub_thread(void *)
// get the parameters // get the parameters
void *address = message.clear_breakpoint.address; void *address = message.clear_breakpoint.address;
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_CLEAR_BREAKPOINT: " TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_CLEAR_BREAKPOINT"
"address: %p\n", nubThread->id, address)); ": address: %p\n", nubThread->id, address));
// check the address // check the address
status_t result = B_OK; status_t result = B_OK;
@@ -1979,9 +1984,9 @@ debug_nub_thread(void *)
uint32 type = message.set_watchpoint.type; uint32 type = message.set_watchpoint.type;
int32 length = message.set_watchpoint.length; int32 length = message.set_watchpoint.length;
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_SET_WATCHPOINT: " TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_SET_WATCHPOINT"
"address: %p, type: %lu, length: %ld\n", nubThread->id, ": address: %p, type: %" B_PRIu32 ", length: %" B_PRId32 "\n",
address, type, length)); nubThread->id, address, type, length));
// check the address and size // check the address and size
status_t result = B_OK; status_t result = B_OK;
@@ -2014,8 +2019,8 @@ debug_nub_thread(void *)
// get the parameters // get the parameters
void *address = message.clear_watchpoint.address; void *address = message.clear_watchpoint.address;
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_CLEAR_WATCHPOINT: " TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_CLEAR_WATCHPOINT"
"address: %p\n", nubThread->id, address)); ": address: %p\n", nubThread->id, address));
// check the address // check the address
status_t result = B_OK; status_t result = B_OK;
@@ -2043,10 +2048,11 @@ debug_nub_thread(void *)
uint32 ignoreOp = message.set_signal_masks.ignore_op; uint32 ignoreOp = message.set_signal_masks.ignore_op;
uint32 ignoreOnceOp = message.set_signal_masks.ignore_once_op; uint32 ignoreOnceOp = message.set_signal_masks.ignore_once_op;
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_SET_SIGNAL_MASKS: " TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_SET_SIGNAL_MASKS"
"thread: %ld, ignore: %llx (op: %lu), ignore once: %llx " ": thread: %" B_PRId32 ", ignore: %" B_PRIx64 " (op: %"
"(op: %lu)\n", nubThread->id, threadID, ignore, B_PRIu32 "), ignore once: %" B_PRIx64 " (op: %" B_PRIu32
ignoreOp, ignoreOnce, ignoreOnceOp)); ")\n", nubThread->id, threadID, ignore, ignoreOp,
ignoreOnce, ignoreOnceOp));
// set the masks // set the masks
Thread* thread = Thread::GetAndLock(threadID); Thread* thread = Thread::GetAndLock(threadID);
@@ -2114,10 +2120,11 @@ debug_nub_thread(void *)
} else } else
result = B_BAD_THREAD_ID; result = B_BAD_THREAD_ID;
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_GET_SIGNAL_MASKS: " TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_GET_SIGNAL_MASKS"
"reply port: %ld, thread: %ld, ignore: %llx, " ": reply port: %" B_PRId32 ", thread: %" B_PRId32 ", "
"ignore once: %llx, result: %lx\n", nubThread->id, "ignore: %" B_PRIx64 ", ignore once: %" B_PRIx64 ", result: "
replyPort, threadID, ignore, ignoreOnce, result)); "%" B_PRIx32 "\n", nubThread->id, replyPort, threadID,
ignore, ignoreOnce, result));
// prepare the message // prepare the message
reply.get_signal_masks.error = result; reply.get_signal_masks.error = result;
@@ -2134,9 +2141,9 @@ debug_nub_thread(void *)
int signal = message.set_signal_handler.signal; int signal = message.set_signal_handler.signal;
struct sigaction &handler = message.set_signal_handler.handler; struct sigaction &handler = message.set_signal_handler.handler;
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_SET_SIGNAL_HANDLER: " TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_SET_SIGNAL_HANDLER"
"signal: %d, handler: %p\n", nubThread->id, ": signal: %d, handler: %p\n", nubThread->id, signal,
signal, handler.sa_handler)); handler.sa_handler));
// set the handler // set the handler
sigaction(signal, &handler, NULL); sigaction(signal, &handler, NULL);
@@ -2157,9 +2164,9 @@ debug_nub_thread(void *)
result = errno; result = errno;
} }
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_GET_SIGNAL_HANDLER: " TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_GET_SIGNAL_HANDLER"
"reply port: %ld, signal: %d, handler: %p\n", nubThread->id, ": reply port: %" B_PRId32 ", signal: %d, handler: %p\n",
replyPort, signal, nubThread->id, replyPort, signal,
reply.get_signal_handler.handler.sa_handler)); reply.get_signal_handler.handler.sa_handler));
// prepare the message // prepare the message
@@ -2171,8 +2178,8 @@ debug_nub_thread(void *)
case B_DEBUG_MESSAGE_PREPARE_HANDOVER: case B_DEBUG_MESSAGE_PREPARE_HANDOVER:
{ {
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_PREPARE_HANDOVER\n", TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_PREPARE_HANDOVER"
nubThread->id)); "\n", nubThread->id));
Team *team = nubThread->team; Team *team = nubThread->team;
@@ -2228,9 +2235,9 @@ debug_nub_thread(void *)
B_DEBUG_MIN_PROFILE_INTERVAL); B_DEBUG_MIN_PROFILE_INTERVAL);
status_t result = B_OK; status_t result = B_OK;
TRACE(("nub thread %ld: B_DEBUG_START_PROFILER: " TRACE(("nub thread %" B_PRId32 ": B_DEBUG_START_PROFILER: "
"thread: %ld, sample area: %ld\n", nubThread->id, threadID, "thread: %" B_PRId32 ", sample area: %" B_PRId32 "\n",
sampleArea)); nubThread->id, threadID, sampleArea));
if (stackDepth < 1) if (stackDepth < 1)
stackDepth = 1; stackDepth = 1;
@@ -2331,8 +2338,8 @@ debug_nub_thread(void *)
replyPort = message.stop_profiler.reply_port; replyPort = message.stop_profiler.reply_port;
status_t result = B_OK; status_t result = B_OK;
TRACE(("nub thread %ld: B_DEBUG_STOP_PROFILER: " TRACE(("nub thread %" B_PRId32 ": B_DEBUG_STOP_PROFILER: "
"thread: %ld\n", nubThread->id, threadID)); "thread: %" B_PRId32 "\n", nubThread->id, threadID));
area_id sampleArea = -1; area_id sampleArea = -1;
addr_t* samples = NULL; addr_t* samples = NULL;
@@ -2407,8 +2414,9 @@ debug_nub_thread(void *)
if (error != B_OK) { if (error != B_OK) {
// The debugger port is either not longer existing or we got // The debugger port is either not longer existing or we got
// interrupted by a kill signal. In either case we terminate. // interrupted by a kill signal. In either case we terminate.
TRACE(("nub thread %ld: failed to send reply to port %ld: %s\n", TRACE(("nub thread %" B_PRId32 ": failed to send reply to port "
nubThread->id, replyPort, strerror(error))); "%" B_PRId32 ": %s\n", nubThread->id, replyPort,
strerror(error)));
nub_thread_cleanup(nubThread); nub_thread_cleanup(nubThread);
return error; return error;
@@ -2470,8 +2478,9 @@ static port_id
install_team_debugger(team_id teamID, port_id debuggerPort, install_team_debugger(team_id teamID, port_id debuggerPort,
thread_id causingThread, bool useDefault, bool dontReplace) thread_id causingThread, bool useDefault, bool dontReplace)
{ {
TRACE(("install_team_debugger(team: %ld, port: %ld, default: %d, " TRACE(("install_team_debugger(team: %" B_PRId32 ", port: %" B_PRId32 ", "
"dontReplace: %d)\n", teamID, debuggerPort, useDefault, dontReplace)); "default: %d, dontReplace: %d)\n", teamID, debuggerPort, useDefault,
dontReplace));
if (useDefault) if (useDefault)
debuggerPort = atomic_get(&sDefaultDebuggerPort); debuggerPort = atomic_get(&sDefaultDebuggerPort);
@@ -2481,7 +2490,7 @@ install_team_debugger(team_id teamID, port_id debuggerPort,
status_t error = get_port_info(debuggerPort, &debuggerPortInfo); status_t error = get_port_info(debuggerPort, &debuggerPortInfo);
if (error != B_OK) { if (error != B_OK) {
TRACE(("install_team_debugger(): Failed to get debugger port info: " TRACE(("install_team_debugger(): Failed to get debugger port info: "
"%lx\n", error)); "%" B_PRIx32 "\n", error));
return error; return error;
} }
team_id debuggerTeam = debuggerPortInfo.team; team_id debuggerTeam = debuggerPortInfo.team;
@@ -2490,7 +2499,8 @@ install_team_debugger(team_id teamID, port_id debuggerPort,
// debugged team. // debugged team.
if (debuggerTeam == team_get_kernel_team_id() || debuggerTeam == teamID) { if (debuggerTeam == team_get_kernel_team_id() || debuggerTeam == teamID) {
TRACE(("install_team_debugger(): Can't debug kernel or debugger team. " TRACE(("install_team_debugger(): Can't debug kernel or debugger team. "
"debugger: %ld, debugged: %ld\n", debuggerTeam, teamID)); "debugger: %" B_PRId32 ", debugged: %" B_PRId32 "\n", debuggerTeam,
teamID));
return B_NOT_ALLOWED; return B_NOT_ALLOWED;
} }
@@ -2618,13 +2628,14 @@ install_team_debugger(team_id teamID, port_id debuggerPort,
} }
TRACE(("install_team_debugger() done: handed over to debugger: team: " TRACE(("install_team_debugger() done: handed over to debugger: team: "
"%ld, port: %ld\n", debuggerTeam, debuggerPort)); "%" B_PRId32 ", port: %" B_PRId32 "\n", debuggerTeam,
debuggerPort));
return result; return result;
} }
if (done || error != B_OK) { if (done || error != B_OK) {
TRACE(("install_team_debugger() done1: %ld\n", TRACE(("install_team_debugger() done1: %" B_PRId32 "\n",
(error == B_OK ? result : error))); (error == B_OK ? result : error)));
finish_debugger_change(team); finish_debugger_change(team);
return (error == B_OK ? result : error); return (error == B_OK ? result : error);
@@ -2708,7 +2719,7 @@ install_team_debugger(team_id teamID, port_id debuggerPort,
delete breakpointManager; delete breakpointManager;
} }
TRACE(("install_team_debugger() done2: %ld\n", TRACE(("install_team_debugger() done2: %" B_PRId32 "\n",
(error == B_OK ? result : error))); (error == B_OK ? result : error)));
return (error == B_OK ? result : error); return (error == B_OK ? result : error);
} }
@@ -2759,7 +2770,8 @@ _user_disable_debugger(int state)
{ {
Team *team = thread_get_current_thread()->team; Team *team = thread_get_current_thread()->team;
TRACE(("_user_disable_debugger(%d): team: %ld\n", state, team->id)); TRACE(("_user_disable_debugger(%d): team: %" B_PRId32 "\n", state,
team->id));
cpu_status cpuState = disable_interrupts(); cpu_status cpuState = disable_interrupts();
GRAB_TEAM_DEBUG_INFO_LOCK(team->debug_info); GRAB_TEAM_DEBUG_INFO_LOCK(team->debug_info);
@@ -2853,7 +2865,8 @@ _user_remove_team_debugger(team_id teamID)
status_t status_t
_user_debug_thread(thread_id threadID) _user_debug_thread(thread_id threadID)
{ {
TRACE(("[%ld] _user_debug_thread(%ld)\n", find_thread(NULL), threadID)); TRACE(("[%" B_PRId32 "] _user_debug_thread(%" B_PRId32 ")\n",
find_thread(NULL), threadID));
// get the thread // get the thread
Thread* thread = Thread::GetAndLock(threadID); Thread* thread = Thread::GetAndLock(threadID);
+3 -6
View File
@@ -2506,8 +2506,6 @@ elf_init(kernel_args *args)
// #pragma mark - // #pragma mark -
// TODO: x86_64
#ifndef __x86_64__
/*! Reads the symbol and string table for the kernel image with the given ID. /*! Reads the symbol and string table for the kernel image with the given ID.
\a _symbolCount and \a _stringTableSize are both in- and output parameters. \a _symbolCount and \a _stringTableSize are both in- and output parameters.
When called they call the size of the buffers given by \a symbolTable and When called they call the size of the buffers given by \a symbolTable and
@@ -2519,7 +2517,7 @@ elf_init(kernel_args *args)
values in the table to get the actual symbol addresses. values in the table to get the actual symbol addresses.
*/ */
status_t status_t
_user_read_kernel_image_symbols(image_id id, struct Elf32_Sym* symbolTable, _user_read_kernel_image_symbols(image_id id, elf_sym* symbolTable,
int32* _symbolCount, char* stringTable, size_t* _stringTableSize, int32* _symbolCount, char* stringTable, size_t* _stringTableSize,
addr_t* _imageDelta) addr_t* _imageDelta)
{ {
@@ -2551,7 +2549,7 @@ _user_read_kernel_image_symbols(image_id id, struct Elf32_Sym* symbolTable,
// get the tables and infos // get the tables and infos
addr_t imageDelta = image->text_region.delta; addr_t imageDelta = image->text_region.delta;
const Elf32_Sym* symbols; const elf_sym* symbols;
int32 symbolCount; int32 symbolCount;
const char* strings; const char* strings;
@@ -2579,7 +2577,7 @@ _user_read_kernel_image_symbols(image_id id, struct Elf32_Sym* symbolTable,
// copy symbol table // copy symbol table
int32 symbolsToCopy = min_c(symbolCount, maxSymbolCount); int32 symbolsToCopy = min_c(symbolCount, maxSymbolCount);
if (symbolTable != NULL && symbolsToCopy > 0) { if (symbolTable != NULL && symbolsToCopy > 0) {
if (user_memcpy(symbolTable, symbols, sizeof(Elf32_Sym) * symbolsToCopy) if (user_memcpy(symbolTable, symbols, sizeof(elf_sym) * symbolsToCopy)
!= B_OK) { != B_OK) {
return B_BAD_ADDRESS; return B_BAD_ADDRESS;
} }
@@ -2605,4 +2603,3 @@ _user_read_kernel_image_symbols(image_id id, struct Elf32_Sym* symbolTable,
return B_OK; return B_OK;
} }
#endif