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:
parent
2b883e1977
commit
8a1903353e
@ -32,7 +32,7 @@ typedef struct x86_64_extended_registers {
|
||||
x86_64_fp_register mmx_registers[8]; // mm0-mm7
|
||||
};
|
||||
x86_64_xmm_register xmm_registers[16]; // xmm0-xmm15
|
||||
uint8 reserved4[96]; // 416 - 512
|
||||
uint8 reserved2[96]; // 416 - 512
|
||||
} x86_64_extended_registers;
|
||||
|
||||
|
||||
@ -58,8 +58,6 @@ struct x86_64_debug_cpu_state {
|
||||
uint64 rcx;
|
||||
uint64 rbx;
|
||||
uint64 rax;
|
||||
uint64 vector;
|
||||
uint64 error_code;
|
||||
uint64 rip;
|
||||
uint64 cs;
|
||||
uint64 rflags;
|
||||
|
@ -263,8 +263,8 @@ typedef struct arch_cpu_info {
|
||||
|
||||
struct X86PagingStructures* active_paging_structures;
|
||||
|
||||
uint32 dr6; // temporary storage for debug registers (cf.
|
||||
uint32 dr7; // x86_exit_user_debug_at_kernel_entry())
|
||||
size_t dr6; // temporary storage for debug registers (cf.
|
||||
size_t dr7; // x86_exit_user_debug_at_kernel_entry())
|
||||
|
||||
// local TSS for this cpu
|
||||
struct tss tss;
|
||||
|
@ -9,8 +9,12 @@
|
||||
#define ARCH_INIT_USER_DEBUG x86_init_user_debug
|
||||
|
||||
// number of breakpoints the CPU supports
|
||||
// Actually it supports 4, but DR3 is used to hold the Thread*.
|
||||
#define X86_BREAKPOINT_COUNT 3
|
||||
// On 32-bit, DR3 is used to hold the Thread*.
|
||||
#ifdef __x86_64__
|
||||
# define X86_BREAKPOINT_COUNT 4
|
||||
#else
|
||||
# define X86_BREAKPOINT_COUNT 3
|
||||
#endif
|
||||
|
||||
// debug status register DR6
|
||||
enum {
|
||||
@ -95,14 +99,14 @@ enum {
|
||||
|
||||
struct arch_breakpoint {
|
||||
void *address; // NULL, if deactivated
|
||||
uint32 type; // one of the architecture types above
|
||||
uint32 length; // one of the length values above
|
||||
size_t type; // one of the architecture types above
|
||||
size_t length; // one of the length values above
|
||||
};
|
||||
|
||||
struct arch_team_debug_info {
|
||||
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 {
|
||||
|
@ -9,6 +9,7 @@
|
||||
#define _KERNEL_ELF_H
|
||||
|
||||
|
||||
#include <elf_common.h>
|
||||
#include <thread.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);
|
||||
status_t elf_init(struct kernel_args *args);
|
||||
|
||||
status_t _user_read_kernel_image_symbols(image_id id,
|
||||
struct Elf32_Sym* symbolTable, int32* _symbolCount,
|
||||
char* stringTable, size_t* _stringTableSize, addr_t* _imageDelta);
|
||||
status_t _user_read_kernel_image_symbols(image_id id, elf_sym* symbolTable,
|
||||
int32* _symbolCount, char* stringTable, size_t* _stringTableSize,
|
||||
addr_t* _imageDelta);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <arch_config.h>
|
||||
#include <DiskDeviceDefs.h>
|
||||
#include <elf_common.h>
|
||||
#include <image.h>
|
||||
#include <OS.h>
|
||||
|
||||
@ -21,7 +22,6 @@ extern "C" {
|
||||
|
||||
struct attr_info;
|
||||
struct dirent;
|
||||
struct Elf32_Sym;
|
||||
struct fd_info;
|
||||
struct fd_set;
|
||||
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,
|
||||
image_info *info, size_t size);
|
||||
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,
|
||||
addr_t* _imageDelta);
|
||||
|
||||
|
@ -72,11 +72,9 @@ arch_int_init(kernel_args* args)
|
||||
table[i] = x86_hardware_interrupt;
|
||||
|
||||
table[0] = x86_unexpected_exception; // Divide Error Exception (#DE)
|
||||
//table[1] = x86_handle_debug_exception; // Debug Exception (#DB)
|
||||
table[1] = x86_unexpected_exception;
|
||||
table[1] = x86_handle_debug_exception; // Debug Exception (#DB)
|
||||
table[2] = x86_fatal_exception; // NMI Interrupt
|
||||
//table[3] = x86_handle_breakpoint_exception; // Breakpoint Exception (#BP)
|
||||
table[3] = x86_unexpected_exception;
|
||||
table[3] = x86_handle_breakpoint_exception; // Breakpoint Exception (#BP)
|
||||
table[4] = x86_unexpected_exception; // Overflow Exception (#OF)
|
||||
table[5] = x86_unexpected_exception; // BOUND Range Exceeded Exception (#BR)
|
||||
table[6] = x86_unexpected_exception; // Invalid Opcode Exception (#UD)
|
||||
|
@ -109,17 +109,12 @@
|
||||
\
|
||||
UNLOCK_THREAD_TIME()
|
||||
|
||||
// TODO
|
||||
#if 0
|
||||
#define STOP_USER_DEBUGGING() \
|
||||
testl $(THREAD_FLAGS_BREAKPOINTS_INSTALLED \
|
||||
| THREAD_FLAGS_SINGLE_STEP), THREAD_flags(%r12); \
|
||||
jz 1f; \
|
||||
call x86_exit_user_debug_at_kernel_entry; \
|
||||
1:
|
||||
#else
|
||||
#define STOP_USER_DEBUGGING()
|
||||
#endif
|
||||
|
||||
|
||||
// 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
|
||||
|
||||
.Lkernel_exit_work_done:
|
||||
// Install breakpoints, if defined. TODO
|
||||
//testl $THREAD_FLAGS_BREAKPOINTS_DEFINED, THREAD_flags(%r12)
|
||||
//jz 1f
|
||||
//movq %rbp, %rdi
|
||||
//call x86_init_user_debug_at_kernel_exit
|
||||
//1:
|
||||
// Install breakpoints, if defined.
|
||||
testl $THREAD_FLAGS_BREAKPOINTS_DEFINED, THREAD_flags(%r12)
|
||||
jz 1f
|
||||
movq %rbp, %rdi
|
||||
call x86_init_user_debug_at_kernel_exit
|
||||
1:
|
||||
// Restore the saved registers.
|
||||
RESTORE_IFRAME()
|
||||
|
||||
@ -333,7 +328,7 @@ FUNCTION(x86_64_syscall_entry):
|
||||
|
||||
// Check whether the syscall number is valid.
|
||||
cmpq $SYSCALL_COUNT, %r14
|
||||
jae .Lbad_syscall_number
|
||||
jae .Lsyscall_return
|
||||
|
||||
// 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,
|
||||
@ -348,6 +343,11 @@ FUNCTION(x86_64_syscall_entry):
|
||||
cmpq $48, %rcx
|
||||
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
|
||||
// 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
|
||||
@ -359,7 +359,7 @@ FUNCTION(x86_64_syscall_entry):
|
||||
movq IFRAME_r8(%rbp), %r8
|
||||
movq IFRAME_r9(%rbp), %r9
|
||||
|
||||
// TODO: pre-syscall tracing/debug
|
||||
// TODO: pre-syscall tracing
|
||||
|
||||
// Call the function and save its return value.
|
||||
call *SYSCALL_INFO_function(%rax)
|
||||
@ -367,7 +367,9 @@ FUNCTION(x86_64_syscall_entry):
|
||||
|
||||
// TODO: post-syscall tracing
|
||||
|
||||
.Lbad_syscall_number:
|
||||
// Restore the original stack pointer and return.
|
||||
movq %rbp, %rsp
|
||||
|
||||
.Lsyscall_return:
|
||||
// Clear the restarted flag.
|
||||
testl $THREAD_FLAGS_SYSCALL_RESTARTED, THREAD_flags(%r12)
|
||||
@ -405,9 +407,41 @@ FUNCTION(x86_64_syscall_entry):
|
||||
swapgs
|
||||
sysretq
|
||||
|
||||
.Lpost_syscall_work:
|
||||
// TODO: post-syscall debugging
|
||||
.Lpre_syscall_debug:
|
||||
// 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?
|
||||
testl $(THREAD_FLAGS_SIGNALS_PENDING | THREAD_FLAGS_DEBUG_THREAD) \
|
||||
, THREAD_flags(%r12)
|
||||
@ -422,11 +456,11 @@ FUNCTION(x86_64_syscall_entry):
|
||||
movq %rsp, %rdi
|
||||
call x86_restart_syscall
|
||||
1:
|
||||
// Install breakpoints, if defined. TODO
|
||||
//testl $THREAD_FLAGS_BREAKPOINTS_DEFINED, THREAD_flags(%r12)
|
||||
//jz .Liret
|
||||
//movq %rbp, %rdi
|
||||
//call x86_init_user_debug_at_kernel_exit
|
||||
// Install breakpoints, if defined.
|
||||
testl $THREAD_FLAGS_BREAKPOINTS_DEFINED, THREAD_flags(%r12)
|
||||
jz .Liret
|
||||
movq %rbp, %rdi
|
||||
call x86_init_user_debug_at_kernel_exit
|
||||
|
||||
// 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
|
||||
@ -470,25 +504,8 @@ FUNCTION(x86_64_syscall_entry):
|
||||
movsq
|
||||
movq $0, THREAD_fault_handler(%r12)
|
||||
|
||||
// Restore the register arguments from the iframe.
|
||||
movq IFRAME_di(%rbp), %rdi
|
||||
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
|
||||
// Perform the call.
|
||||
jmp .Lperform_syscall
|
||||
|
||||
.Lbad_syscall_args:
|
||||
movq $0, THREAD_fault_handler(%r12)
|
||||
|
@ -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;
|
||||
}
|
@ -24,7 +24,6 @@ if $(TARGET_ARCH) = x86_64 {
|
||||
cpuid.S
|
||||
int.cpp
|
||||
interrupts.S
|
||||
stubs.cpp
|
||||
signals.cpp
|
||||
signals_asm.S
|
||||
syscalls.cpp
|
||||
@ -56,7 +55,6 @@ if $(TARGET_ARCH) = x86_64 {
|
||||
syscalls_asm.S
|
||||
thread.cpp
|
||||
|
||||
arch_user_debugger.cpp
|
||||
ioapic.cpp
|
||||
irq_routing_table.cpp
|
||||
|
||||
@ -88,6 +86,7 @@ local archGenericSources =
|
||||
arch_system_info.cpp
|
||||
arch_thread.cpp
|
||||
arch_timer.cpp
|
||||
arch_user_debugger.cpp
|
||||
arch_vm.cpp
|
||||
arch_vm_translation_map.cpp
|
||||
apic.cpp
|
||||
|
@ -39,27 +39,27 @@ extern bool gHasSSE;
|
||||
const uint8 kX86SoftwareBreakpoint[1] = { 0xcc };
|
||||
|
||||
// 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
|
||||
};
|
||||
|
||||
// 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
|
||||
};
|
||||
|
||||
// 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
|
||||
};
|
||||
|
||||
// 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
|
||||
};
|
||||
|
||||
// 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
|
||||
};
|
||||
|
||||
@ -68,8 +68,78 @@ static const uint32 sDR6B[4] = {
|
||||
static bool sQEmuSingleStepHack = false;
|
||||
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
||||
|
||||
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->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
|
||||
install_breakpoints(const arch_team_debug_info &teamInfo)
|
||||
install_breakpoints(const arch_team_debug_info& teamInfo)
|
||||
{
|
||||
// set breakpoints
|
||||
asm("movl %0, %%dr0" : : "r"(teamInfo.breakpoints[0].address));
|
||||
asm("movl %0, %%dr1" : : "r"(teamInfo.breakpoints[1].address));
|
||||
asm("movl %0, %%dr2" : : "r"(teamInfo.breakpoints[2].address));
|
||||
// asm("movl %0, %%dr3" : : "r"(teamInfo.breakpoints[3].address));
|
||||
// DR3 is used to hold the current Thread*.
|
||||
asm("mov %0, %%dr0" : : "r"(teamInfo.breakpoints[0].address));
|
||||
asm("mov %0, %%dr1" : : "r"(teamInfo.breakpoints[1].address));
|
||||
asm("mov %0, %%dr2" : : "r"(teamInfo.breakpoints[2].address));
|
||||
#ifdef __x86_64__
|
||||
asm("mov %0, %%dr3" : : "r"(teamInfo.breakpoints[3].address));
|
||||
// DR3 is used to hold the current Thread* on 32.
|
||||
#endif
|
||||
|
||||
// enable breakpoints
|
||||
asm("movl %0, %%dr7" : : "r"(teamInfo.dr7));
|
||||
asm("mov %0, %%dr7" : : "r"(teamInfo.dr7));
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
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.
|
||||
*/
|
||||
static inline status_t
|
||||
set_breakpoint(arch_team_debug_info &info, void *address, uint32 type,
|
||||
uint32 length, bool setGlobalFlag)
|
||||
set_breakpoint(arch_team_debug_info& info, void* address, size_t type,
|
||||
size_t length, bool setGlobalFlag)
|
||||
{
|
||||
// check, if there is already a breakpoint at that address
|
||||
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.
|
||||
*/
|
||||
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
|
||||
int32 slot = -1;
|
||||
@ -202,12 +303,12 @@ clear_breakpoint(arch_team_debug_info &info, void *address, bool watchpoint)
|
||||
|
||||
|
||||
static status_t
|
||||
set_breakpoint(void *address, uint32 type, uint32 length)
|
||||
set_breakpoint(void* address, size_t type, size_t length)
|
||||
{
|
||||
if (!address)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
Thread *thread = thread_get_current_thread();
|
||||
Thread* thread = thread_get_current_thread();
|
||||
|
||||
cpu_status state = disable_interrupts();
|
||||
GRAB_TEAM_DEBUG_INFO_LOCK(thread->team->debug_info);
|
||||
@ -223,12 +324,12 @@ set_breakpoint(void *address, uint32 type, uint32 length)
|
||||
|
||||
|
||||
static status_t
|
||||
clear_breakpoint(void *address, bool watchpoint)
|
||||
clear_breakpoint(void* address, bool watchpoint)
|
||||
{
|
||||
if (!address)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
Thread *thread = thread_get_current_thread();
|
||||
Thread* thread = thread_get_current_thread();
|
||||
|
||||
cpu_status state = disable_interrupts();
|
||||
GRAB_TEAM_DEBUG_INFO_LOCK(thread->team->debug_info);
|
||||
@ -260,7 +361,7 @@ install_breakpoints_per_cpu(void* /*cookie*/, int cpu)
|
||||
|
||||
|
||||
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)
|
||||
return B_BAD_VALUE;
|
||||
@ -284,7 +385,7 @@ set_kernel_breakpoint(void *address, uint32 type, uint32 length)
|
||||
|
||||
|
||||
static status_t
|
||||
clear_kernel_breakpoint(void *address, bool watchpoint)
|
||||
clear_kernel_breakpoint(void* address, bool watchpoint)
|
||||
{
|
||||
if (!address)
|
||||
return B_BAD_VALUE;
|
||||
@ -311,7 +412,7 @@ clear_kernel_breakpoint(void *address, bool watchpoint)
|
||||
|
||||
static inline status_t
|
||||
check_watch_point_parameters(void* address, uint32 type, int32 length,
|
||||
uint32& archType, uint32& archLength)
|
||||
size_t& archType, size_t& archLength)
|
||||
{
|
||||
// check type
|
||||
switch (type) {
|
||||
@ -333,12 +434,12 @@ check_watch_point_parameters(void* address, uint32 type, int32 length,
|
||||
archLength = X86_BREAKPOINT_LENGTH_1;
|
||||
break;
|
||||
case 2:
|
||||
if ((uint32)address & 0x1)
|
||||
if ((addr_t)address & 0x1)
|
||||
return B_BAD_WATCHPOINT_ALIGNMENT;
|
||||
archLength = X86_BREAKPOINT_LENGTH_2;
|
||||
break;
|
||||
case 4:
|
||||
if ((uint32)address & 0x3)
|
||||
if ((addr_t)address & 0x3)
|
||||
return B_BAD_WATCHPOINT_ALIGNMENT;
|
||||
archLength = X86_BREAKPOINT_LENGTH_4;
|
||||
break;
|
||||
@ -352,6 +453,7 @@ check_watch_point_parameters(void* address, uint32 type, int32 length,
|
||||
|
||||
// #pragma mark - kernel debugger commands
|
||||
|
||||
|
||||
#if KERNEL_BREAKPOINTS
|
||||
|
||||
static int
|
||||
@ -361,7 +463,7 @@ debugger_breakpoints(int argc, char** argv)
|
||||
arch_team_debug_info& info = kernelTeam->debug_info.arch_info;
|
||||
|
||||
for (int32 i = 0; i < X86_BREAKPOINT_COUNT; i++) {
|
||||
kprintf("breakpoint[%ld] ", i);
|
||||
kprintf("breakpoint[%" B_PRId32 "] ", i);
|
||||
|
||||
if (info.breakpoints[i].address != NULL) {
|
||||
kprintf("%p ", info.breakpoints[i].address);
|
||||
@ -491,7 +593,7 @@ debugger_watchpoint(int argc, char** argv)
|
||||
uint32 type = readWrite ? B_DATA_READ_WRITE_WATCHPOINT
|
||||
: B_DATA_WRITE_WATCHPOINT;
|
||||
|
||||
uint32 archType, archLength;
|
||||
size_t archType, archLength;
|
||||
error = check_watch_point_parameters((void*)address, type, length,
|
||||
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
|
||||
// via an exception.
|
||||
|
||||
struct iframe* frame = x86_get_current_iframe();
|
||||
iframe* frame = x86_get_current_iframe();
|
||||
if (frame == NULL) {
|
||||
kprintf("Failed to get the current iframe!\n");
|
||||
return 0;
|
||||
@ -535,7 +637,7 @@ debugger_single_step(int argc, char** argv)
|
||||
|
||||
|
||||
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++)
|
||||
info->breakpoints[i].address = NULL;
|
||||
@ -545,21 +647,21 @@ arch_clear_team_debug_info(struct arch_team_debug_info *info)
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
@ -568,7 +670,7 @@ arch_destroy_thread_debug_info(struct arch_thread_debug_info *info)
|
||||
void
|
||||
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();
|
||||
|
||||
// set/clear TF in EFLAGS depending on whether single stepping is
|
||||
@ -582,9 +684,9 @@ arch_update_thread_single_step()
|
||||
|
||||
|
||||
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
|
||||
// not use these registers (not even indirectly).
|
||||
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,
|
||||
sizeof(cpuState->extended_registers));
|
||||
x86_fxrstor(thread->arch_info.fpu_state);
|
||||
#ifndef __x86_64__
|
||||
} else {
|
||||
// TODO: Implement! We need to convert the format first.
|
||||
// x86_frstor(&cpuState->extended_registers);
|
||||
#endif
|
||||
}
|
||||
|
||||
// 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;
|
||||
set_iframe_registers(frame, cpuState);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
// not use these registers (not even indirectly).
|
||||
if (gHasSSE) {
|
||||
@ -642,12 +726,14 @@ arch_get_debug_cpu_state(debug_cpu_state *cpuState)
|
||||
// unlike fnsave, fxsave doesn't reinit the FPU state
|
||||
memcpy(&cpuState->extended_registers, thread->arch_info.fpu_state,
|
||||
sizeof(cpuState->extended_registers));
|
||||
#ifndef __x86_64__
|
||||
} else {
|
||||
x86_fnsave(&cpuState->extended_registers);
|
||||
x86_frstor(&cpuState->extended_registers);
|
||||
// fnsave reinits the FPU state after saving, so we need to
|
||||
// load it again
|
||||
// TODO: Convert to fxsave format!
|
||||
#endif
|
||||
}
|
||||
get_iframe_registers(frame, cpuState);
|
||||
}
|
||||
@ -655,7 +741,7 @@ arch_get_debug_cpu_state(debug_cpu_state *cpuState)
|
||||
|
||||
|
||||
status_t
|
||||
arch_set_breakpoint(void *address)
|
||||
arch_set_breakpoint(void* address)
|
||||
{
|
||||
return set_breakpoint(address, X86_INSTRUCTION_BREAKPOINT,
|
||||
X86_BREAKPOINT_LENGTH_1);
|
||||
@ -663,16 +749,16 @@ arch_set_breakpoint(void *address)
|
||||
|
||||
|
||||
status_t
|
||||
arch_clear_breakpoint(void *address)
|
||||
arch_clear_breakpoint(void* address)
|
||||
{
|
||||
return clear_breakpoint(address, false);
|
||||
}
|
||||
|
||||
|
||||
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,
|
||||
archType, archLength);
|
||||
if (error != B_OK)
|
||||
@ -683,14 +769,14 @@ arch_set_watchpoint(void *address, uint32 type, int32 length)
|
||||
|
||||
|
||||
status_t
|
||||
arch_clear_watchpoint(void *address)
|
||||
arch_clear_watchpoint(void* address)
|
||||
{
|
||||
return clear_breakpoint(address, true);
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
// 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
|
||||
|
||||
status_t
|
||||
arch_set_kernel_breakpoint(void *address)
|
||||
arch_set_kernel_breakpoint(void* address)
|
||||
{
|
||||
status_t error = set_kernel_breakpoint(address, X86_INSTRUCTION_BREAKPOINT,
|
||||
X86_BREAKPOINT_LENGTH_1);
|
||||
@ -716,7 +802,7 @@ arch_set_kernel_breakpoint(void *address)
|
||||
|
||||
|
||||
status_t
|
||||
arch_clear_kernel_breakpoint(void *address)
|
||||
arch_clear_kernel_breakpoint(void* address)
|
||||
{
|
||||
status_t error = clear_kernel_breakpoint(address, false);
|
||||
|
||||
@ -730,9 +816,9 @@ arch_clear_kernel_breakpoint(void *address)
|
||||
|
||||
|
||||
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,
|
||||
archType, archLength);
|
||||
|
||||
@ -749,7 +835,7 @@ arch_set_kernel_watchpoint(void *address, uint32 type, int32 length)
|
||||
|
||||
|
||||
status_t
|
||||
arch_clear_kernel_watchpoint(void *address)
|
||||
arch_clear_kernel_watchpoint(void* address)
|
||||
{
|
||||
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.
|
||||
*/
|
||||
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))
|
||||
return;
|
||||
@ -800,14 +886,14 @@ x86_init_user_debug_at_kernel_exit(struct iframe *frame)
|
||||
void
|
||||
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,
|
||||
// since in case of a debug exception we might overwrite them before
|
||||
// x86_handle_debug_exception() is called. Debug exceptions occur when
|
||||
// hitting a hardware break/watchpoint or when single-stepping.
|
||||
asm("movl %%dr6, %0" : "=r"(thread->cpu->arch.dr6));
|
||||
asm("movl %%dr7, %0" : "=r"(thread->cpu->arch.dr7));
|
||||
asm("mov %%dr6, %0" : "=r"(thread->cpu->arch.dr6));
|
||||
asm("mov %%dr7, %0" : "=r"(thread->cpu->arch.dr7));
|
||||
|
||||
// The remainder needs only be done, when user breakpoints are 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.
|
||||
*/
|
||||
void
|
||||
x86_handle_debug_exception(struct iframe *frame)
|
||||
x86_handle_debug_exception(iframe* frame)
|
||||
{
|
||||
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
|
||||
// and dr7 are stored in the cpu info. Otherwise we need to fetch the
|
||||
// current values from the registers.
|
||||
uint32 dr6;
|
||||
uint32 dr7;
|
||||
size_t dr6;
|
||||
size_t dr7;
|
||||
if (IFRAME_IS_USER(frame)) {
|
||||
dr6 = thread->cpu->arch.dr6;
|
||||
dr7 = thread->cpu->arch.dr7;
|
||||
} else {
|
||||
asm("movl %%dr6, %0" : "=r"(dr6));
|
||||
asm("movl %%dr7, %0" : "=r"(dr7));
|
||||
asm("mov %%dr6, %0" : "=r"(dr6));
|
||||
asm("mov %%dr7, %0" : "=r"(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;
|
||||
for (int32 i = 0; i < X86_BREAKPOINT_COUNT; i++) {
|
||||
if (dr6 & (1 << sDR6B[i])) {
|
||||
uint32 type = (dr7 >> sDR7RW[i]) & 0x3;
|
||||
size_t type = (dr7 >> sDR7RW[i]) & 0x3;
|
||||
if (type == X86_INSTRUCTION_BREAKPOINT)
|
||||
watchpoint = false;
|
||||
}
|
||||
@ -972,7 +1058,7 @@ x86_handle_debug_exception(struct iframe *frame)
|
||||
* Interrupts are disabled and will possibly be enabled by the function.
|
||||
*/
|
||||
void
|
||||
x86_handle_breakpoint_exception(struct iframe *frame)
|
||||
x86_handle_breakpoint_exception(iframe* frame)
|
||||
{
|
||||
TRACE(("x86_handle_breakpoint_exception()\n"));
|
||||
|
||||
@ -994,7 +1080,7 @@ void
|
||||
x86_init_user_debug()
|
||||
{
|
||||
// get debug settings
|
||||
if (void *handle = load_driver_settings("kernel")) {
|
||||
if (void* handle = load_driver_settings("kernel")) {
|
||||
sQEmuSingleStepHack = get_driver_boolean_parameter(handle,
|
||||
"qemu_single_step_hack", false, false);;
|
||||
|
||||
|
@ -77,8 +77,9 @@ static status_t
|
||||
debugger_write(port_id port, int32 code, const void *buffer, size_t bufferSize,
|
||||
bool dontWait)
|
||||
{
|
||||
TRACE(("debugger_write(): thread: %ld, team %ld, port: %ld, code: %lx, message: %p, "
|
||||
"size: %lu, dontWait: %d\n", thread_get_current_thread()->id,
|
||||
TRACE(("debugger_write(): thread: %" B_PRId32 ", team %" B_PRId32 ", "
|
||||
"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,
|
||||
dontWait));
|
||||
|
||||
@ -94,7 +95,7 @@ debugger_write(port_id port, int32 code, const void *buffer, size_t bufferSize,
|
||||
error = acquire_sem_etc(writeLock, 1,
|
||||
dontWait ? (uint32)B_RELATIVE_TIMEOUT : (uint32)B_KILL_CAN_INTERRUPT, 0);
|
||||
if (error != B_OK) {
|
||||
TRACE(("debugger_write() done1: %lx\n", error));
|
||||
TRACE(("debugger_write() done1: %" B_PRIx32 "\n", 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_sem(writeLock);
|
||||
|
||||
TRACE(("debugger_write() done: %lx\n", error));
|
||||
TRACE(("debugger_write() done: %" B_PRIx32 "\n", error));
|
||||
|
||||
return error;
|
||||
}
|
||||
@ -529,8 +530,9 @@ thread_hit_debug_event_internal(debug_debugger_message event,
|
||||
restart = false;
|
||||
Thread *thread = thread_get_current_thread();
|
||||
|
||||
TRACE(("thread_hit_debug_event(): thread: %ld, event: %lu, message: %p, "
|
||||
"size: %ld\n", thread->id, (uint32)event, message, size));
|
||||
TRACE(("thread_hit_debug_event(): thread: %" B_PRId32 ", event: %" B_PRIu32
|
||||
", message: %p, size: %" B_PRId32 "\n", thread->id, (uint32)event,
|
||||
message, size));
|
||||
|
||||
// check, if there's a debug port already
|
||||
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);
|
||||
if (thread->id == thread->team->debug_info.nub_thread) {
|
||||
// Ugh, we're the nub thread. We shouldn't be here.
|
||||
TRACE(("thread_hit_debug_event(): Misdirected nub thread: %ld\n",
|
||||
thread->id));
|
||||
TRACE(("thread_hit_debug_event(): Misdirected nub thread: %" B_PRId32
|
||||
"\n", thread->id));
|
||||
|
||||
error = B_ERROR;
|
||||
} else if (debuggerInstalled || !requireDebugger) {
|
||||
@ -614,8 +616,8 @@ thread_hit_debug_event_internal(debug_debugger_message event,
|
||||
delete_port(deletePort);
|
||||
|
||||
if (error != B_OK) {
|
||||
TRACE(("thread_hit_debug_event() error: thread: %ld, error: %lx\n",
|
||||
thread->id, error));
|
||||
TRACE(("thread_hit_debug_event() error: thread: %" B_PRId32 ", error: "
|
||||
"%" B_PRIx32 "\n", thread->id, error));
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -627,8 +629,9 @@ thread_hit_debug_event_internal(debug_debugger_message event,
|
||||
origin->team = thread->team->id;
|
||||
origin->nub_port = nubPort;
|
||||
|
||||
TRACE(("thread_hit_debug_event(): thread: %ld, sending message to "
|
||||
"debugger port %ld\n", thread->id, debuggerPort));
|
||||
TRACE(("thread_hit_debug_event(): thread: %" B_PRId32 ", sending "
|
||||
"message to debugger port %" B_PRId32 "\n", thread->id,
|
||||
debuggerPort));
|
||||
|
||||
error = debugger_write(debuggerPort, event, message, size, false);
|
||||
}
|
||||
@ -648,15 +651,15 @@ thread_hit_debug_event_internal(debug_debugger_message event,
|
||||
|
||||
if (commandMessageSize < 0) {
|
||||
error = commandMessageSize;
|
||||
TRACE(("thread_hit_debug_event(): thread: %ld, failed "
|
||||
"to receive message from port %ld: %lx\n",
|
||||
TRACE(("thread_hit_debug_event(): thread: %" B_PRId32 ", failed "
|
||||
"to receive message from port %" B_PRId32 ": %" B_PRIx32 "\n",
|
||||
thread->id, port, error));
|
||||
break;
|
||||
}
|
||||
|
||||
switch (command) {
|
||||
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",
|
||||
thread->id));
|
||||
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:
|
||||
{
|
||||
TRACE(("thread_hit_debug_event(): thread: %ld: "
|
||||
TRACE(("thread_hit_debug_event(): thread: %" B_PRId32 ": "
|
||||
"B_DEBUGGED_THREAD_SET_CPU_STATE\n",
|
||||
thread->id));
|
||||
arch_set_debug_cpu_state(
|
||||
@ -720,9 +723,9 @@ thread_hit_debug_event_internal(debug_debugger_message event,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
TRACE(("thread_hit_debug_event(): thread: %ld, failed to send "
|
||||
"message to debugger port %ld: %lx\n", thread->id,
|
||||
debuggerPort, error));
|
||||
TRACE(("thread_hit_debug_event(): thread: %" B_PRId32 ", failed to send "
|
||||
"message to debugger port %" B_PRId32 ": %" B_PRIx32 "\n",
|
||||
thread->id, debuggerPort, error));
|
||||
}
|
||||
|
||||
// update the thread debug info
|
||||
@ -993,8 +996,8 @@ void
|
||||
user_debug_team_deleted(team_id teamID, port_id debuggerPort)
|
||||
{
|
||||
if (debuggerPort >= 0) {
|
||||
TRACE(("user_debug_team_deleted(team: %ld, debugger port: %ld)\n",
|
||||
teamID, debuggerPort));
|
||||
TRACE(("user_debug_team_deleted(team: %" B_PRId32 ", debugger port: "
|
||||
"%" B_PRId32 ")\n", teamID, debuggerPort));
|
||||
|
||||
debug_team_deleted message;
|
||||
message.origin.thread = -1;
|
||||
@ -1541,7 +1544,8 @@ broadcast_debugged_thread_message(Thread *nubThread, int32 code,
|
||||
code, message, size);
|
||||
if (error != B_OK) {
|
||||
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
|
||||
nub_thread_cleanup(Thread *nubThread)
|
||||
{
|
||||
TRACE(("nub_thread_cleanup(%ld): debugger port: %ld\n", nubThread->id,
|
||||
nubThread->team->debug_info.debugger_port));
|
||||
TRACE(("nub_thread_cleanup(%" B_PRId32 "): debugger port: %" B_PRId32 "\n",
|
||||
nubThread->id, nubThread->team->debug_info.debugger_port));
|
||||
|
||||
ConditionVariable debugChangeCondition;
|
||||
prepare_debugger_change(nubThread->team, debugChangeCondition);
|
||||
@ -1654,8 +1658,8 @@ debug_nub_thread(void *)
|
||||
RELEASE_TEAM_DEBUG_INFO_LOCK(nubThread->team->debug_info);
|
||||
restore_interrupts(state);
|
||||
|
||||
TRACE(("debug_nub_thread() thread: %ld, team %ld, nub port: %ld\n",
|
||||
nubThread->id, nubThread->team->id, port));
|
||||
TRACE(("debug_nub_thread() thread: %" B_PRId32 ", team %" B_PRId32 ", nub "
|
||||
"port: %" B_PRId32 "\n", nubThread->id, nubThread->team->id, port));
|
||||
|
||||
// notify all threads that a debugger has been installed
|
||||
broadcast_debugged_thread_message(nubThread,
|
||||
@ -1674,8 +1678,8 @@ debug_nub_thread(void *)
|
||||
// thread, we need to update that.
|
||||
nub_thread_cleanup(nubThread);
|
||||
|
||||
TRACE(("nub thread %ld: terminating: %lx\n", nubThread->id,
|
||||
messageSize));
|
||||
TRACE(("nub thread %" B_PRId32 ": terminating: %lx\n",
|
||||
nubThread->id, messageSize));
|
||||
|
||||
return messageSize;
|
||||
}
|
||||
@ -1719,10 +1723,10 @@ debug_nub_thread(void *)
|
||||
}
|
||||
reply.read_memory.error = result;
|
||||
|
||||
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_READ_MEMORY: "
|
||||
"reply port: %ld, address: %p, size: %ld, result: %lx, "
|
||||
"read: %ld\n", nubThread->id, replyPort, address, size,
|
||||
result, bytesRead));
|
||||
TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_READ_MEMORY: "
|
||||
"reply port: %" B_PRId32 ", address: %p, size: %" B_PRId32
|
||||
", result: %" B_PRIx32 ", read: %ld\n", nubThread->id,
|
||||
replyPort, address, size, result, bytesRead));
|
||||
|
||||
// send only as much data as necessary
|
||||
reply.read_memory.size = bytesRead;
|
||||
@ -1755,10 +1759,10 @@ debug_nub_thread(void *)
|
||||
}
|
||||
reply.write_memory.error = result;
|
||||
|
||||
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_WRITE_MEMORY: "
|
||||
"reply port: %ld, address: %p, size: %ld, result: %lx, "
|
||||
"written: %ld\n", nubThread->id, replyPort, address, size,
|
||||
result, bytesWritten));
|
||||
TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_WRITE_MEMORY: "
|
||||
"reply port: %" B_PRId32 ", address: %p, size: %" B_PRId32
|
||||
", result: %" B_PRIx32 ", written: %ld\n", nubThread->id,
|
||||
replyPort, address, size, result, bytesWritten));
|
||||
|
||||
reply.write_memory.size = bytesWritten;
|
||||
sendReply = true;
|
||||
@ -1772,8 +1776,8 @@ debug_nub_thread(void *)
|
||||
int32 flags = message.set_team_flags.flags
|
||||
& B_TEAM_DEBUG_USER_FLAG_MASK;
|
||||
|
||||
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_SET_TEAM_FLAGS: "
|
||||
"flags: %lx\n", nubThread->id, flags));
|
||||
TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_SET_TEAM_FLAGS"
|
||||
": flags: %" B_PRIx32 "\n", nubThread->id, flags));
|
||||
|
||||
Team *team = thread_get_current_thread()->team;
|
||||
|
||||
@ -1797,9 +1801,9 @@ debug_nub_thread(void *)
|
||||
int32 flags = message.set_thread_flags.flags
|
||||
& B_THREAD_DEBUG_USER_FLAG_MASK;
|
||||
|
||||
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_SET_THREAD_FLAGS: "
|
||||
"thread: %ld, flags: %lx\n", nubThread->id, threadID,
|
||||
flags));
|
||||
TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_SET_THREAD_FLAGS"
|
||||
": thread: %" B_PRId32 ", flags: %" B_PRIx32 "\n",
|
||||
nubThread->id, threadID, flags));
|
||||
|
||||
// set the flags
|
||||
Thread* thread = Thread::GetAndLock(threadID);
|
||||
@ -1831,9 +1835,10 @@ debug_nub_thread(void *)
|
||||
handleEvent = message.continue_thread.handle_event;
|
||||
singleStep = message.continue_thread.single_step;
|
||||
|
||||
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_CONTINUE_THREAD: "
|
||||
"thread: %ld, handle event: %lu, single step: %d\n",
|
||||
nubThread->id, threadID, handleEvent, singleStep));
|
||||
TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_CONTINUE_THREAD"
|
||||
": thread: %" B_PRId32 ", handle event: %" B_PRIu32 ", "
|
||||
"single step: %d\n", nubThread->id, threadID, handleEvent,
|
||||
singleStep));
|
||||
|
||||
// find the thread and get its debug port
|
||||
port_id threadDebugPort = -1;
|
||||
@ -1861,8 +1866,8 @@ debug_nub_thread(void *)
|
||||
const debug_cpu_state &cpuState
|
||||
= message.set_cpu_state.cpu_state;
|
||||
|
||||
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_SET_CPU_STATE: "
|
||||
"thread: %ld\n", nubThread->id, threadID));
|
||||
TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_SET_CPU_STATE"
|
||||
": thread: %" B_PRId32 "\n", nubThread->id, threadID));
|
||||
|
||||
// find the thread and get its debug port
|
||||
port_id threadDebugPort = -1;
|
||||
@ -1888,8 +1893,8 @@ debug_nub_thread(void *)
|
||||
thread_id threadID = message.get_cpu_state.thread;
|
||||
replyPort = message.get_cpu_state.reply_port;
|
||||
|
||||
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_GET_CPU_STATE: "
|
||||
"thread: %ld\n", nubThread->id, threadID));
|
||||
TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_GET_CPU_STATE"
|
||||
": thread: %" B_PRId32 "\n", nubThread->id, threadID));
|
||||
|
||||
// find the thread and get its debug port
|
||||
port_id threadDebugPort = -1;
|
||||
@ -1921,8 +1926,8 @@ debug_nub_thread(void *)
|
||||
replyPort = message.set_breakpoint.reply_port;
|
||||
void *address = message.set_breakpoint.address;
|
||||
|
||||
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_SET_BREAKPOINT: "
|
||||
"address: %p\n", nubThread->id, address));
|
||||
TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_SET_BREAKPOINT"
|
||||
": address: %p\n", nubThread->id, address));
|
||||
|
||||
// check the address
|
||||
status_t result = B_OK;
|
||||
@ -1951,8 +1956,8 @@ debug_nub_thread(void *)
|
||||
// get the parameters
|
||||
void *address = message.clear_breakpoint.address;
|
||||
|
||||
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_CLEAR_BREAKPOINT: "
|
||||
"address: %p\n", nubThread->id, address));
|
||||
TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_CLEAR_BREAKPOINT"
|
||||
": address: %p\n", nubThread->id, address));
|
||||
|
||||
// check the address
|
||||
status_t result = B_OK;
|
||||
@ -1979,9 +1984,9 @@ debug_nub_thread(void *)
|
||||
uint32 type = message.set_watchpoint.type;
|
||||
int32 length = message.set_watchpoint.length;
|
||||
|
||||
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_SET_WATCHPOINT: "
|
||||
"address: %p, type: %lu, length: %ld\n", nubThread->id,
|
||||
address, type, length));
|
||||
TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_SET_WATCHPOINT"
|
||||
": address: %p, type: %" B_PRIu32 ", length: %" B_PRId32 "\n",
|
||||
nubThread->id, address, type, length));
|
||||
|
||||
// check the address and size
|
||||
status_t result = B_OK;
|
||||
@ -2014,8 +2019,8 @@ debug_nub_thread(void *)
|
||||
// get the parameters
|
||||
void *address = message.clear_watchpoint.address;
|
||||
|
||||
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_CLEAR_WATCHPOINT: "
|
||||
"address: %p\n", nubThread->id, address));
|
||||
TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_CLEAR_WATCHPOINT"
|
||||
": address: %p\n", nubThread->id, address));
|
||||
|
||||
// check the address
|
||||
status_t result = B_OK;
|
||||
@ -2043,10 +2048,11 @@ debug_nub_thread(void *)
|
||||
uint32 ignoreOp = message.set_signal_masks.ignore_op;
|
||||
uint32 ignoreOnceOp = message.set_signal_masks.ignore_once_op;
|
||||
|
||||
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_SET_SIGNAL_MASKS: "
|
||||
"thread: %ld, ignore: %llx (op: %lu), ignore once: %llx "
|
||||
"(op: %lu)\n", nubThread->id, threadID, ignore,
|
||||
ignoreOp, ignoreOnce, ignoreOnceOp));
|
||||
TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_SET_SIGNAL_MASKS"
|
||||
": thread: %" B_PRId32 ", ignore: %" B_PRIx64 " (op: %"
|
||||
B_PRIu32 "), ignore once: %" B_PRIx64 " (op: %" B_PRIu32
|
||||
")\n", nubThread->id, threadID, ignore, ignoreOp,
|
||||
ignoreOnce, ignoreOnceOp));
|
||||
|
||||
// set the masks
|
||||
Thread* thread = Thread::GetAndLock(threadID);
|
||||
@ -2114,10 +2120,11 @@ debug_nub_thread(void *)
|
||||
} else
|
||||
result = B_BAD_THREAD_ID;
|
||||
|
||||
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_GET_SIGNAL_MASKS: "
|
||||
"reply port: %ld, thread: %ld, ignore: %llx, "
|
||||
"ignore once: %llx, result: %lx\n", nubThread->id,
|
||||
replyPort, threadID, ignore, ignoreOnce, result));
|
||||
TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_GET_SIGNAL_MASKS"
|
||||
": reply port: %" B_PRId32 ", thread: %" B_PRId32 ", "
|
||||
"ignore: %" B_PRIx64 ", ignore once: %" B_PRIx64 ", result: "
|
||||
"%" B_PRIx32 "\n", nubThread->id, replyPort, threadID,
|
||||
ignore, ignoreOnce, result));
|
||||
|
||||
// prepare the message
|
||||
reply.get_signal_masks.error = result;
|
||||
@ -2134,9 +2141,9 @@ debug_nub_thread(void *)
|
||||
int signal = message.set_signal_handler.signal;
|
||||
struct sigaction &handler = message.set_signal_handler.handler;
|
||||
|
||||
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_SET_SIGNAL_HANDLER: "
|
||||
"signal: %d, handler: %p\n", nubThread->id,
|
||||
signal, handler.sa_handler));
|
||||
TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_SET_SIGNAL_HANDLER"
|
||||
": signal: %d, handler: %p\n", nubThread->id, signal,
|
||||
handler.sa_handler));
|
||||
|
||||
// set the handler
|
||||
sigaction(signal, &handler, NULL);
|
||||
@ -2157,9 +2164,9 @@ debug_nub_thread(void *)
|
||||
result = errno;
|
||||
}
|
||||
|
||||
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_GET_SIGNAL_HANDLER: "
|
||||
"reply port: %ld, signal: %d, handler: %p\n", nubThread->id,
|
||||
replyPort, signal,
|
||||
TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_GET_SIGNAL_HANDLER"
|
||||
": reply port: %" B_PRId32 ", signal: %d, handler: %p\n",
|
||||
nubThread->id, replyPort, signal,
|
||||
reply.get_signal_handler.handler.sa_handler));
|
||||
|
||||
// prepare the message
|
||||
@ -2171,8 +2178,8 @@ debug_nub_thread(void *)
|
||||
|
||||
case B_DEBUG_MESSAGE_PREPARE_HANDOVER:
|
||||
{
|
||||
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_PREPARE_HANDOVER\n",
|
||||
nubThread->id));
|
||||
TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_PREPARE_HANDOVER"
|
||||
"\n", nubThread->id));
|
||||
|
||||
Team *team = nubThread->team;
|
||||
|
||||
@ -2228,9 +2235,9 @@ debug_nub_thread(void *)
|
||||
B_DEBUG_MIN_PROFILE_INTERVAL);
|
||||
status_t result = B_OK;
|
||||
|
||||
TRACE(("nub thread %ld: B_DEBUG_START_PROFILER: "
|
||||
"thread: %ld, sample area: %ld\n", nubThread->id, threadID,
|
||||
sampleArea));
|
||||
TRACE(("nub thread %" B_PRId32 ": B_DEBUG_START_PROFILER: "
|
||||
"thread: %" B_PRId32 ", sample area: %" B_PRId32 "\n",
|
||||
nubThread->id, threadID, sampleArea));
|
||||
|
||||
if (stackDepth < 1)
|
||||
stackDepth = 1;
|
||||
@ -2331,8 +2338,8 @@ debug_nub_thread(void *)
|
||||
replyPort = message.stop_profiler.reply_port;
|
||||
status_t result = B_OK;
|
||||
|
||||
TRACE(("nub thread %ld: B_DEBUG_STOP_PROFILER: "
|
||||
"thread: %ld\n", nubThread->id, threadID));
|
||||
TRACE(("nub thread %" B_PRId32 ": B_DEBUG_STOP_PROFILER: "
|
||||
"thread: %" B_PRId32 "\n", nubThread->id, threadID));
|
||||
|
||||
area_id sampleArea = -1;
|
||||
addr_t* samples = NULL;
|
||||
@ -2407,8 +2414,9 @@ debug_nub_thread(void *)
|
||||
if (error != B_OK) {
|
||||
// The debugger port is either not longer existing or we got
|
||||
// interrupted by a kill signal. In either case we terminate.
|
||||
TRACE(("nub thread %ld: failed to send reply to port %ld: %s\n",
|
||||
nubThread->id, replyPort, strerror(error)));
|
||||
TRACE(("nub thread %" B_PRId32 ": failed to send reply to port "
|
||||
"%" B_PRId32 ": %s\n", nubThread->id, replyPort,
|
||||
strerror(error)));
|
||||
|
||||
nub_thread_cleanup(nubThread);
|
||||
return error;
|
||||
@ -2470,8 +2478,9 @@ static port_id
|
||||
install_team_debugger(team_id teamID, port_id debuggerPort,
|
||||
thread_id causingThread, bool useDefault, bool dontReplace)
|
||||
{
|
||||
TRACE(("install_team_debugger(team: %ld, port: %ld, default: %d, "
|
||||
"dontReplace: %d)\n", teamID, debuggerPort, useDefault, dontReplace));
|
||||
TRACE(("install_team_debugger(team: %" B_PRId32 ", port: %" B_PRId32 ", "
|
||||
"default: %d, dontReplace: %d)\n", teamID, debuggerPort, useDefault,
|
||||
dontReplace));
|
||||
|
||||
if (useDefault)
|
||||
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);
|
||||
if (error != B_OK) {
|
||||
TRACE(("install_team_debugger(): Failed to get debugger port info: "
|
||||
"%lx\n", error));
|
||||
"%" B_PRIx32 "\n", error));
|
||||
return error;
|
||||
}
|
||||
team_id debuggerTeam = debuggerPortInfo.team;
|
||||
@ -2490,7 +2499,8 @@ install_team_debugger(team_id teamID, port_id debuggerPort,
|
||||
// debugged team.
|
||||
if (debuggerTeam == team_get_kernel_team_id() || debuggerTeam == teamID) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -2618,13 +2628,14 @@ install_team_debugger(team_id teamID, port_id debuggerPort,
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)));
|
||||
finish_debugger_change(team);
|
||||
return (error == B_OK ? result : error);
|
||||
@ -2708,7 +2719,7 @@ install_team_debugger(team_id teamID, port_id debuggerPort,
|
||||
delete breakpointManager;
|
||||
}
|
||||
|
||||
TRACE(("install_team_debugger() done2: %ld\n",
|
||||
TRACE(("install_team_debugger() done2: %" B_PRId32 "\n",
|
||||
(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;
|
||||
|
||||
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();
|
||||
GRAB_TEAM_DEBUG_INFO_LOCK(team->debug_info);
|
||||
@ -2853,7 +2865,8 @@ _user_remove_team_debugger(team_id teamID)
|
||||
status_t
|
||||
_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
|
||||
Thread* thread = Thread::GetAndLock(threadID);
|
||||
|
@ -2506,8 +2506,6 @@ elf_init(kernel_args *args)
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
// TODO: x86_64
|
||||
#ifndef __x86_64__
|
||||
/*! 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.
|
||||
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.
|
||||
*/
|
||||
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,
|
||||
addr_t* _imageDelta)
|
||||
{
|
||||
@ -2551,7 +2549,7 @@ _user_read_kernel_image_symbols(image_id id, struct Elf32_Sym* symbolTable,
|
||||
|
||||
// get the tables and infos
|
||||
addr_t imageDelta = image->text_region.delta;
|
||||
const Elf32_Sym* symbols;
|
||||
const elf_sym* symbols;
|
||||
int32 symbolCount;
|
||||
const char* strings;
|
||||
|
||||
@ -2579,7 +2577,7 @@ _user_read_kernel_image_symbols(image_id id, struct Elf32_Sym* symbolTable,
|
||||
// copy symbol table
|
||||
int32 symbolsToCopy = min_c(symbolCount, maxSymbolCount);
|
||||
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) {
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
@ -2605,4 +2603,3 @@ _user_read_kernel_image_symbols(image_id id, struct Elf32_Sym* symbolTable,
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user