* Copyright 2005-2016 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _DEBUGGER_H
#define _DEBUGGER_H
#include <signal.h>
#include <image.h>
#include <OS.h>
#include <arch/x86/arch_debugger.h>
#include <arch/x86_64/arch_debugger.h>
#include <arch/ppc/arch_debugger.h>
#include <arch/m68k/arch_debugger.h>
#include <arch/mipsel/arch_debugger.h>
#include <arch/arm/arch_debugger.h>
#include <arch/arm64/arch_debugger.h>
#include <arch/riscv64/arch_debugger.h>
#include <arch/sparc/arch_debugger.h>
#if defined(__x86_64__)
typedef struct x86_64_debug_cpu_state debug_cpu_state;
#elif defined(__i386__)
typedef struct x86_debug_cpu_state debug_cpu_state;
#elif defined(__POWERPC__)
typedef struct ppc_debug_cpu_state debug_cpu_state;
#elif defined(__M68K__)
typedef struct m68k_debug_cpu_state debug_cpu_state;
#elif defined(__MIPSEL__)
typedef struct mipsel_debug_cpu_state debug_cpu_state;
#elif defined(__arm__)
typedef struct arm_debug_cpu_state debug_cpu_state;
#elif (defined(__riscv) && __riscv_xlen == 64)
typedef struct riscv64_debug_cpu_state debug_cpu_state;
#elif defined(__sparc64__)
typedef struct sparc_debug_cpu_state debug_cpu_state;
#elif defined(__aarch64__) || defined(__arm64__)
typedef struct arm64_debug_cpu_state debug_cpu_state;
#else
#error unsupported architecture
#endif
#ifdef __cplusplus
extern "C" {
#endif
extern status_t install_default_debugger(port_id debuggerPort);
extern port_id install_team_debugger(team_id team, port_id debuggerPort);
extern status_t remove_team_debugger(team_id team);
extern status_t debug_thread(thread_id thread);
extern void wait_for_debugger(void);
extern status_t set_debugger_breakpoint(void *address);
extern status_t clear_debugger_breakpoint(void *address);
extern status_t set_debugger_watchpoint(void *address, uint32 type,
int32 length);
extern status_t clear_debugger_watchpoint(void *address);
enum {
B_TEAM_DEBUG_SIGNALS = 0x00010000,
B_TEAM_DEBUG_PRE_SYSCALL = 0x00020000,
B_TEAM_DEBUG_POST_SYSCALL = 0x00040000,
B_TEAM_DEBUG_TEAM_CREATION = 0x00080000,
B_TEAM_DEBUG_THREADS = 0x00100000,
B_TEAM_DEBUG_IMAGES = 0x00200000,
B_TEAM_DEBUG_PREVENT_EXIT = 0x00400000,
B_TEAM_DEBUG_STOP_NEW_THREADS = 0x01000000,
B_TEAM_DEBUG_USER_FLAG_MASK = 0xffff0000,
};
enum {
B_THREAD_DEBUG_PRE_SYSCALL = 0x00010000,
B_THREAD_DEBUG_POST_SYSCALL = 0x00020000,
B_THREAD_DEBUG_STOP_CHILD_THREADS = 0x00100000,
B_THREAD_DEBUG_SYSCALL_TRACE_CHILD_THREADS = 0x00200000,
B_THREAD_DEBUG_USER_FLAG_MASK = 0xffff0000,
};
typedef enum {
B_NON_MASKABLE_INTERRUPT = 0,
B_MACHINE_CHECK_EXCEPTION,
B_SEGMENT_VIOLATION,
B_ALIGNMENT_EXCEPTION,
B_DIVIDE_ERROR,
B_OVERFLOW_EXCEPTION,
B_BOUNDS_CHECK_EXCEPTION,
B_INVALID_OPCODE_EXCEPTION,
B_SEGMENT_NOT_PRESENT,
B_STACK_FAULT,
B_GENERAL_PROTECTION_FAULT,
B_FLOATING_POINT_EXCEPTION,
} debug_exception_type;
enum {
B_THREAD_DEBUG_HANDLE_EVENT = 0,
B_THREAD_DEBUG_IGNORE_EVENT,
};
enum {
B_DATA_READ_WATCHPOINT = 0,
B_DATA_WRITE_WATCHPOINT,
B_DATA_READ_WRITE_WATCHPOINT,
};
typedef enum {
B_DEBUG_SIGNAL_MASK_AND = 0,
B_DEBUG_SIGNAL_MASK_OR,
B_DEBUG_SIGNAL_MASK_SET,
} debug_signal_mask_op;
#define B_DEBUG_SIGNAL_TO_MASK(signal) (1ULL << ((signal) - 1))
enum {
B_MAX_READ_WRITE_MEMORY_SIZE = 1024,
};
typedef enum {
B_DEBUG_MESSAGE_READ_MEMORY = 0,
B_DEBUG_MESSAGE_WRITE_MEMORY,
B_DEBUG_MESSAGE_SET_TEAM_FLAGS,
B_DEBUG_MESSAGE_SET_THREAD_FLAGS,
B_DEBUG_MESSAGE_CONTINUE_THREAD,
B_DEBUG_MESSAGE_SET_CPU_STATE,
B_DEBUG_MESSAGE_GET_CPU_STATE,
B_DEBUG_MESSAGE_SET_BREAKPOINT,
B_DEBUG_MESSAGE_CLEAR_BREAKPOINT,
B_DEBUG_MESSAGE_SET_WATCHPOINT,
B_DEBUG_MESSAGE_CLEAR_WATCHPOINT,
B_DEBUG_MESSAGE_SET_SIGNAL_MASKS,
B_DEBUG_MESSAGE_GET_SIGNAL_MASKS,
B_DEBUG_MESSAGE_SET_SIGNAL_HANDLER,
B_DEBUG_MESSAGE_GET_SIGNAL_HANDLER,
B_DEBUG_MESSAGE_CLONE_AREA,
B_DEBUG_MESSAGE_PREPARE_HANDOVER = 1000,
B_DEBUG_MESSAGE_WRITE_CORE_FILE,
B_DEBUG_MESSAGE_START_PROFILER = 2000,
B_DEBUG_MESSAGE_STOP_PROFILER,
} debug_nub_message;
typedef enum {
B_DEBUGGER_MESSAGE_THREAD_DEBUGGED = 0,
B_DEBUGGER_MESSAGE_DEBUGGER_CALL,
B_DEBUGGER_MESSAGE_BREAKPOINT_HIT,
B_DEBUGGER_MESSAGE_WATCHPOINT_HIT,
B_DEBUGGER_MESSAGE_SINGLE_STEP,
B_DEBUGGER_MESSAGE_PRE_SYSCALL,
B_DEBUGGER_MESSAGE_POST_SYSCALL,
B_DEBUGGER_MESSAGE_SIGNAL_RECEIVED,
B_DEBUGGER_MESSAGE_EXCEPTION_OCCURRED,
B_DEBUGGER_MESSAGE_TEAM_CREATED,
B_DEBUGGER_MESSAGE_TEAM_DELETED,
B_DEBUGGER_MESSAGE_TEAM_EXEC,
B_DEBUGGER_MESSAGE_THREAD_CREATED,
B_DEBUGGER_MESSAGE_THREAD_DELETED,
B_DEBUGGER_MESSAGE_IMAGE_CREATED,
B_DEBUGGER_MESSAGE_IMAGE_DELETED,
B_DEBUGGER_MESSAGE_PROFILER_UPDATE,
B_DEBUGGER_MESSAGE_HANDED_OVER,
} debug_debugger_message;
enum {
B_DEBUG_PROFILE_EVENT_BASE = 0x80000000,
B_DEBUG_PROFILE_EVENT_PARAMETER_MASK = 0x0000ffff,
B_DEBUG_PROFILE_IMAGE_EVENT = 0x80010001
};
typedef struct {
port_id reply_port;
void *address;
int32 size;
} debug_nub_read_memory;
typedef struct {
status_t error;
int32 size;
char data[B_MAX_READ_WRITE_MEMORY_SIZE];
} debug_nub_read_memory_reply;
typedef struct {
port_id reply_port;
void *address;
int32 size;
char data[B_MAX_READ_WRITE_MEMORY_SIZE];
} debug_nub_write_memory;
typedef struct {
status_t error;
int32 size;
} debug_nub_write_memory_reply;
typedef struct {
port_id reply_port;
const void *address;
} debug_nub_clone_area;
typedef struct {
area_id area;
const void *address;
} debug_nub_clone_area_reply;
typedef struct {
int32 flags;
} debug_nub_set_team_flags;
typedef struct {
thread_id thread;
int32 flags;
} debug_nub_set_thread_flags;
typedef struct {
thread_id thread;
uint32 handle_event;
bool single_step;
} debug_nub_continue_thread;
typedef struct {
thread_id thread;
debug_cpu_state cpu_state;
} debug_nub_set_cpu_state;
typedef struct {
port_id reply_port;
thread_id thread;
} debug_nub_get_cpu_state;
typedef struct {
status_t error;
debug_debugger_message message;
debug_cpu_state cpu_state;
} debug_nub_get_cpu_state_reply;
typedef struct {
port_id reply_port;
void *address;
} debug_nub_set_breakpoint;
typedef struct {
status_t error;
} debug_nub_set_breakpoint_reply;
typedef struct {
void *address;
} debug_nub_clear_breakpoint;
typedef struct {
port_id reply_port;
void *address;
uint32 type;
int32 length;
} debug_nub_set_watchpoint;
typedef struct {
status_t error;
} debug_nub_set_watchpoint_reply;
typedef struct {
void *address;
} debug_nub_clear_watchpoint;
typedef struct {
thread_id thread;
uint64 ignore_mask;
uint64 ignore_once_mask;
debug_signal_mask_op ignore_op;
debug_signal_mask_op ignore_once_op;
} debug_nub_set_signal_masks;
typedef struct {
port_id reply_port;
thread_id thread;
} debug_nub_get_signal_masks;
typedef struct {
status_t error;
uint64 ignore_mask;
uint64 ignore_once_mask;
} debug_nub_get_signal_masks_reply;
typedef struct {
int signal;
struct sigaction handler;
} debug_nub_set_signal_handler;
typedef struct {
port_id reply_port;
int signal;
} debug_nub_get_signal_handler;
typedef struct {
status_t error;
struct sigaction handler;
} debug_nub_get_signal_handler_reply;
struct debug_profile_function {
addr_t base;
size_t size;
};
typedef struct {
port_id reply_port;
thread_id thread;
bigtime_t interval;
area_id sample_area;
int32 stack_depth;
bool variable_stack_depth;
bool profile_kernel;
} debug_nub_start_profiler;
typedef struct {
status_t error;
int32 image_event;
bigtime_t interval;
} debug_nub_start_profiler_reply;
typedef struct {
port_id reply_port;
thread_id thread;
} debug_nub_stop_profiler;
typedef struct {
port_id reply_port;
char path[B_PATH_NAME_LENGTH];
} debug_nub_write_core_file;
typedef struct {
status_t error;
} debug_nub_write_core_file_reply;
typedef union {
debug_nub_read_memory read_memory;
debug_nub_write_memory write_memory;
debug_nub_clone_area clone_area;
debug_nub_set_team_flags set_team_flags;
debug_nub_set_thread_flags set_thread_flags;
debug_nub_continue_thread continue_thread;
debug_nub_set_cpu_state set_cpu_state;
debug_nub_get_cpu_state get_cpu_state;
debug_nub_set_breakpoint set_breakpoint;
debug_nub_clear_breakpoint clear_breakpoint;
debug_nub_set_watchpoint set_watchpoint;
debug_nub_clear_watchpoint clear_watchpoint;
debug_nub_set_signal_masks set_signal_masks;
debug_nub_get_signal_masks get_signal_masks;
debug_nub_set_signal_handler set_signal_handler;
debug_nub_get_signal_handler get_signal_handler;
debug_nub_start_profiler start_profiler;
debug_nub_stop_profiler stop_profiler;
debug_nub_write_core_file write_core_file;
} debug_nub_message_data;
typedef struct {
thread_id thread;
team_id team;
port_id nub_port;
} debug_origin;
typedef struct {
debug_origin origin;
} debug_thread_debugged;
typedef struct {
debug_origin origin;
void *message;
} debug_debugger_call;
typedef struct {
debug_origin origin;
debug_cpu_state cpu_state;
} debug_breakpoint_hit;
typedef struct {
debug_origin origin;
debug_cpu_state cpu_state;
} debug_watchpoint_hit;
typedef struct {
debug_origin origin;
debug_cpu_state cpu_state;
} debug_single_step;
typedef struct {
debug_origin origin;
uint32 syscall;
uint8 args[128];
} debug_pre_syscall;
typedef struct {
debug_origin origin;
bigtime_t start_time;
bigtime_t end_time;
uint64 return_value;
uint32 syscall;
uint8 args[128];
} debug_post_syscall;
typedef struct {
debug_origin origin;
int signal;
struct sigaction handler;
siginfo_t info;
bool deadly;
} debug_signal_received;
typedef struct {
debug_origin origin;
debug_exception_type exception;
int signal;
} debug_exception_occurred;
typedef struct {
debug_origin origin;
team_id new_team;
} debug_team_created;
typedef struct {
debug_origin origin;
status_t status;
int signal;
team_usage_info usage;
} debug_team_deleted;
typedef struct {
debug_origin origin;
int32 image_event;
} debug_team_exec;
typedef struct {
debug_origin origin;
team_id new_thread;
} debug_thread_created;
typedef struct {
debug_origin origin;
status_t status;
} debug_thread_deleted;
typedef struct {
debug_origin origin;
image_info info;
int32 image_event;
} debug_image_created;
typedef struct {
debug_origin origin;
image_info info;
int32 image_event;
} debug_image_deleted;
typedef struct {
debug_origin origin;
int32 image_event;
int32 stack_depth;
int32 sample_count;
int32 dropped_ticks;
bool variable_stack_depth;
bool stopped;
bigtime_t last_cpu_time;
} debug_profiler_update;
typedef struct {
debug_origin origin;
team_id debugger;
port_id debugger_port;
thread_id causing_thread;
} debug_handed_over;
typedef union {
debug_thread_debugged thread_debugged;
debug_debugger_call debugger_call;
debug_breakpoint_hit breakpoint_hit;
debug_watchpoint_hit watchpoint_hit;
debug_single_step single_step;
debug_pre_syscall pre_syscall;
debug_post_syscall post_syscall;
debug_signal_received signal_received;
debug_exception_occurred exception_occurred;
debug_team_created team_created;
debug_team_deleted team_deleted;
debug_team_exec team_exec;
debug_thread_created thread_created;
debug_thread_deleted thread_deleted;
debug_image_created image_created;
debug_image_deleted image_deleted;
debug_profiler_update profiler_update;
debug_handed_over handed_over;
debug_origin origin;
} debug_debugger_message_data;
extern void get_debug_message_string(debug_debugger_message message,
char *buffer, int32 bufferSize);
extern void get_debug_exception_string(debug_exception_type exception,
char *buffer, int32 bufferSize);
#ifdef __cplusplus
}
#endif
#endif