Bochs/bochs/bx_debug/debug.h
Volker Ruppert f348c6cf50 - fixed broken debugger "rc file" command line option. Now it is possible to
execute debugger commands from the specified file. This is the command line
  counterpart to the undocumented debugger command "source".
2006-10-24 17:53:47 +00:00

512 lines
14 KiB
C

/////////////////////////////////////////////////////////////////////////
// $Id: debug.h,v 1.30 2006-10-24 17:53:47 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
//
// MandrakeSoft S.A.
// 43, rue d'Aboukir
// 75002 Paris - France
// http://www.linux-mandrake.com/
// http://www.mandrakesoft.com/
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// if including from C parser, need basic types etc
#include "config.h"
#include "osdep.h"
#define BX_DBG_NO_HANDLE 1000
extern Bit32u dbg_cpu;
Bit32u crc32(const Bit8u *buf, int len);
#if BX_DEBUGGER
// some strict C declarations needed by the parser/lexer
#ifdef __cplusplus
extern "C" {
#endif
void dbg_printf (const char *fmt, ...);
typedef enum {
BX_DBG_SREG_ES,
BX_DBG_SREG_CS,
BX_DBG_SREG_SS,
BX_DBG_SREG_DS,
BX_DBG_SREG_FS,
BX_DBG_SREG_GS
} SRegs;
#if BX_SUPPORT_X86_64
# define BX_DBG_GEN_REGISTERS 16
#else
# define BX_DBG_GEN_REGISTERS 8
#endif
typedef enum {
BX_DBG_REG8H_AH,
BX_DBG_REG8H_CH,
BX_DBG_REG8H_DH,
BX_DBG_REG8H_BH,
} Regs8H;
#if BX_SUPPORT_X86_64
typedef enum {
BX_DBG_REG8L_AL,
BX_DBG_REG8L_CL,
BX_DBG_REG8L_DL,
BX_DBG_REG8L_BL,
BX_DBG_REG8L_SPL,
BX_DBG_REG8L_BPL,
BX_DBG_REG8L_SIL,
BX_DBG_REG8L_DIL,
BX_DBG_REG8L_R8,
BX_DBG_REG8L_R9,
BX_DBG_REG8L_R10,
BX_DBG_REG8L_R11,
BX_DBG_REG8L_R12,
BX_DBG_REG8L_R13,
BX_DBG_REG8L_R14,
BX_DBG_REG8L_R15
} Regs8L;
typedef enum {
BX_DBG_REG16_AX,
BX_DBG_REG16_CX,
BX_DBG_REG16_DX,
BX_DBG_REG16_BX,
BX_DBG_REG16_SP,
BX_DBG_REG16_BP,
BX_DBG_REG16_SI,
BX_DBG_REG16_DI,
BX_DBG_REG16_R8,
BX_DBG_REG16_R9,
BX_DBG_REG16_R10,
BX_DBG_REG16_R11,
BX_DBG_REG16_R12,
BX_DBG_REG16_R13,
BX_DBG_REG16_R14,
BX_DBG_REG16_R15
} Regs16;
typedef enum {
BX_DBG_REG32_EAX,
BX_DBG_REG32_ECX,
BX_DBG_REG32_EDX,
BX_DBG_REG32_EBX,
BX_DBG_REG32_ESP,
BX_DBG_REG32_EBP,
BX_DBG_REG32_ESI,
BX_DBG_REG32_EDI,
BX_DBG_REG32_R8,
BX_DBG_REG32_R9,
BX_DBG_REG32_R10,
BX_DBG_REG32_R11,
BX_DBG_REG32_R12,
BX_DBG_REG32_R13,
BX_DBG_REG32_R14,
BX_DBG_REG32_R15
} Regs32;
typedef enum {
BX_DBG_REG64_RAX,
BX_DBG_REG64_RCX,
BX_DBG_REG64_RDX,
BX_DBG_REG64_RBX,
BX_DBG_REG64_RSP,
BX_DBG_REG64_RBP,
BX_DBG_REG64_RSI,
BX_DBG_REG64_RDI,
BX_DBG_REG64_R8,
BX_DBG_REG64_R9,
BX_DBG_REG64_R10,
BX_DBG_REG64_R11,
BX_DBG_REG64_R12,
BX_DBG_REG64_R13,
BX_DBG_REG64_R14,
BX_DBG_REG64_R15
} Regs64;
#else
typedef enum {
BX_DBG_REG8L_AL,
BX_DBG_REG8L_CL,
BX_DBG_REG8L_DL,
BX_DBG_REG8L_BL
} Regs8L;
typedef enum {
BX_DBG_REG16_AX,
BX_DBG_REG16_CX,
BX_DBG_REG16_DX,
BX_DBG_REG16_BX,
BX_DBG_REG16_SP,
BX_DBG_REG16_BP,
BX_DBG_REG16_SI,
BX_DBG_REG16_DI
} Regs16;
typedef enum {
BX_DBG_REG32_EAX,
BX_DBG_REG32_ECX,
BX_DBG_REG32_EDX,
BX_DBG_REG32_EBX,
BX_DBG_REG32_ESP,
BX_DBG_REG32_EBP,
BX_DBG_REG32_ESI,
BX_DBG_REG32_EDI
} Regs32;
#endif
typedef enum
{
bkRegular,
bkAtIP,
bkStepOver
} BreakpointKind;
typedef enum _show_flags {
Flag_call = 0x1,
Flag_ret = 0x2,
Flag_softint = 0x4,
Flag_iret = 0x8,
Flag_intsig = 0x10,
Flag_mode = 0x20
} show_flags_t;
// Flex defs
extern int bxlex(void);
extern char *bxtext; // Using the pointer option rather than array
extern int bxwrap(void);
void bx_add_lex_input(char *buf);
// Yacc defs
extern int bxparse(void);
extern void bxerror(char *s);
#define EMPTY_ARG (-1)
Bit16u bx_dbg_get_selector_value(unsigned int seg_no);
Bit16u bx_dbg_get_ip (void);
Bit32u bx_dbg_get_eip(void);
bx_address bx_dbg_get_instruction_pointer(void);
Bit8u bx_dbg_get_reg8l_value(unsigned reg);
Bit8u bx_dbg_get_reg8h_value(unsigned reg);
Bit16u bx_dbg_get_reg16_value(unsigned reg);
Bit32u bx_dbg_get_reg32_value(unsigned reg);
Bit64u bx_dbg_get_reg64_value(unsigned reg);
void bx_dbg_set_reg8l_value(unsigned reg, Bit8u value);
void bx_dbg_set_reg8h_value(unsigned reg, Bit8u value);
void bx_dbg_set_reg16_value(unsigned reg, Bit16u value);
void bx_dbg_set_reg32_value(unsigned reg, Bit32u value);
void bx_dbg_set_reg64_value(unsigned reg, Bit64u value);
Bit32u bx_dbg_get_laddr(Bit16u sel, Bit32u ofs);
void bx_dbg_step_over_command(void);
void bx_dbg_trace_command(bx_bool enable);
void bx_dbg_trace_reg_command(bx_bool enable);
void bx_dbg_ptime_command(void);
void bx_dbg_timebp_command(bx_bool absolute, Bit64u time);
#define MAX_CONCURRENT_BPS 5
extern int timebp_timer;
extern Bit64u timebp_queue[MAX_CONCURRENT_BPS];
extern int timebp_queue_size;
void bx_dbg_record_command(char*);
void bx_dbg_playback_command(char*);
void bx_dbg_modebp_command(void);
void bx_dbg_where_command(void);
void bx_dbg_print_string_command(bx_address addr);
void bx_dbg_show_command(const char*);
void bx_dbg_show_param_command(char *param);
void bx_dbg_print_stack_command(unsigned nwords);
void bx_dbg_watch(int read, Bit32u address);
void bx_dbg_unwatch(int read, Bit32u address);
void bx_dbg_continue_command(void);
void bx_dbg_stepN_command(Bit32u count);
void bx_dbg_set_auto_disassemble(bx_bool enable);
void bx_dbg_disassemble_switch_mode(void);
void bx_dbg_set_disassemble_size(unsigned size);
void bx_dbg_del_breakpoint_command(unsigned handle);
void bx_dbg_en_dis_breakpoint_command(unsigned handle, bx_bool enable);
bx_bool bx_dbg_en_dis_pbreak(unsigned handle, bx_bool enable);
bx_bool bx_dbg_en_dis_lbreak(unsigned handle, bx_bool enable);
bx_bool bx_dbg_en_dis_vbreak(unsigned handle, bx_bool enable);
bx_bool bx_dbg_del_pbreak(unsigned handle);
bx_bool bx_dbg_del_lbreak(unsigned handle);
bx_bool bx_dbg_del_vbreak(unsigned handle);
int bx_dbg_vbreakpoint_command(BreakpointKind bk, Bit32u cs, bx_address eip);
int bx_dbg_lbreakpoint_command(BreakpointKind bk, bx_address laddress);
int bx_dbg_pbreakpoint_command(BreakpointKind bk, Bit32u paddress);
void bx_dbg_info_bpoints_command(void);
void bx_dbg_quit_command(void);
#define BX_INFO_CPU_REGS 1 /* bitmasks - choices for bx_dbg_info_registers_command */
#define BX_INFO_FPU_REGS 2
#define BX_INFO_SSE_REGS 4
void bx_dbg_info_registers_command(int);
void bx_dbg_info_dirty_command(void);
void bx_dbg_info_ivt_command(unsigned from, unsigned to);
void bx_dbg_info_idt_command(unsigned from, unsigned to);
void bx_dbg_info_gdt_command(unsigned from, unsigned to);
void bx_dbg_info_ldt_command(unsigned from, unsigned to);
void bx_dbg_info_tss_command(void);
void bx_dbg_info_control_regs_command(void);
void bx_dbg_info_flags(void);
void bx_dbg_info_linux_command(void);
void bx_dbg_examine_command(char *command, char *format, bx_bool format_passed,
Bit32u addr, bx_bool addr_passed);
void bx_dbg_setpmem_command(Bit32u addr, unsigned len, Bit32u val);
void bx_dbg_query_command(const char *);
void bx_dbg_take_command(const char *, unsigned n);
void bx_dbg_dump_cpu_command(void);
void bx_dbg_set_cpu_command(void);
void bx_dbg_disassemble_current(const char *);
void bx_dbg_disassemble_command(const char *, Bit64u from, Bit64u to);
void bx_dbg_instrument_command(const char *);
void bx_dbg_doit_command(unsigned);
void bx_dbg_crc_command(Bit32u addr1, Bit32u addr2);
extern bx_bool watchpoint_continue;
void bx_dbg_linux_syscall(unsigned which_cpu);
void bx_dbg_info_ne2k(int page, int reg);
void bx_dbg_info_pic(void);
void bx_dbg_info_vga(void);
void bx_dbg_print_help(void);
void bx_dbg_calc_command(Bit64u value);
void bx_dbg_dump_table(void);
void bx_dbg_exception(unsigned cpu, Bit8u vector, Bit16u error_code);
void bx_dbg_interrupt(unsigned cpu, Bit8u vector, Bit16u error_code);
int bx_dbg_show_symbolic(void);
void bx_dbg_set_symbol_command(char *symbol, Bit32u val);
char* bx_dbg_symbolic_address(Bit32u context, Bit32u eip, Bit32u base);
char* bx_dbg_symbolic_address_16bit(Bit32u eip, Bit32u cs);
void bx_dbg_symbol_command(char* filename, bx_bool global, Bit32u offset);
void bx_dbg_info_symbols_command(char *Symbol);
int bx_dbg_lbreakpoint_symbol_command(char *Symbol);
Bit32u bx_dbg_get_symbol_value(char *Symbol);
char* bx_dbg_disasm_symbolic_address(Bit32u eip, Bit32u base);
#ifdef __cplusplus
}
#endif
// the rest for C++
#ifdef __cplusplus
// Read/write watchpoint hack
#define MAX_WRITE_WATCHPOINTS 16
#define MAX_READ_WATCHPOINTS 16
extern int num_write_watchpoints;
extern Bit32u write_watchpoint[MAX_WRITE_WATCHPOINTS];
extern int num_read_watchpoints;
extern Bit32u read_watchpoint[MAX_READ_WATCHPOINTS];
typedef enum {
STOP_NO_REASON = 0,
STOP_TIME_BREAK_POINT,
STOP_READ_WATCH_POINT,
STOP_WRITE_WATCH_POINT,
STOP_MAGIC_BREAK_POINT,
STOP_MODE_BREAK_POINT,
STOP_CPU_HALTED
} stop_reason_t;
typedef enum {
BREAK_POINT_MAGIC, BREAK_POINT_READ, BREAK_POINT_WRITE, BREAK_POINT_TIME
} break_point_t;
#define BX_DBG_REG_EIP 10
#define BX_DBG_REG_EFLAGS 11
#define BX_DBG_REG_CS 20
#define BX_DBG_REG_SS 21
#define BX_DBG_REG_DS 22
#define BX_DBG_REG_ES 23
#define BX_DBG_REG_FS 24
#define BX_DBG_REG_GS 25
#define BX_DBG_REG_CR0 30
#define BX_DBG_REG_CR2 32
#define BX_DBG_REG_CR3 33
#define BX_DBG_REG_CR4 34
#define BX_DBG_PENDING_DMA 1
#define BX_DBG_PENDING_IRQ 2
void bx_debug_break(void);
void bx_dbg_exit(int code);
#if BX_DBG_EXTENSIONS
int bx_dbg_extensions(char *command);
#else
#define bx_dbg_extensions(command) 0
#endif
//
// code for guards...
//
#define BX_DBG_GUARD_IADDR_VIR 0x0001
#define BX_DBG_GUARD_IADDR_LIN 0x0002
#define BX_DBG_GUARD_IADDR_PHY 0x0004
#define BX_DBG_GUARD_IADDR_ALL (BX_DBG_GUARD_IADDR_VIR | \
BX_DBG_GUARD_IADDR_LIN | \
BX_DBG_GUARD_IADDR_PHY)
#define BX_DBG_GUARD_CTRL_C 0x0100
typedef struct {
unsigned long guard_for;
// instruction address breakpoints
struct {
#if BX_DBG_SUPPORT_VIR_BPOINT
unsigned num_virtual;
struct {
Bit32u cs; // only use 16 bits
bx_address eip;
unsigned bpoint_id;
bx_bool enabled;
} vir[BX_DBG_MAX_VIR_BPOINTS];
#endif
#if BX_DBG_SUPPORT_LIN_BPOINT
unsigned num_linear;
struct {
bx_address addr;
unsigned bpoint_id;
bx_bool enabled;
} lin[BX_DBG_MAX_LIN_BPOINTS];
#endif
#if BX_DBG_SUPPORT_PHY_BPOINT
unsigned num_physical;
struct {
Bit32u addr; // physical address in 32 bits only
unsigned bpoint_id;
bx_bool enabled;
} phy[BX_DBG_MAX_PHY_BPOINTS];
#endif
} iaddr;
// user typed Ctrl-C, requesting simulator stop at next convient spot
volatile bx_bool interrupt_requested;
// booleans to control whether simulator should report events
// to debug controller
struct {
bx_bool irq;
bx_bool a20;
bx_bool io;
bx_bool ucmem;
bx_bool dma;
} report;
struct {
bx_bool irq; // should process IRQs asynchronously
bx_bool dma; // should process DMAs asynchronously
} async;
#define BX_DBG_ASYNC_PENDING_A20 0x01
#define BX_DBG_ASYNC_PENDING_RESET 0x02
#define BX_DBG_ASYNC_PENDING_NMI 0x04
// Asynchronous changes which are pending. These are Q'd by
// the debugger, as the master simulator is notified of a pending
// async change. At the simulator's next point, where it checks for
// such events, it notifies the debugger with acknowlegement. This
// field contains a logically or'd list of all events which should
// be checked, and ack'd.
struct {
unsigned which; // logical OR of above constants
bx_bool a20;
bx_bool reset;
bx_bool nmi;
} async_changes_pending;
} bx_guard_t;
// working information for each simulator to update when a guard
// is reached (found)
typedef struct bx_guard_found_t {
unsigned long guard_found;
unsigned iaddr_index;
Bit32u icount; // number of completed instructions
Bit32u cs; // cs:eip and linear addr of instruction at guard point
bx_address eip;
bx_address laddr;
bx_bool is_32bit_code; // CS seg size at guard point
bx_bool is_64bit_code;
bx_bool ctrl_c; // simulator stopped due to Ctrl-C request
Bit64u time_tick; // time tick when guard reached
} bx_guard_found_t;
extern bx_guard_t bx_guard;
void bx_dbg_init_infile(void);
int bx_dbg_set_rcfile(const char *rcfile);
int bx_dbg_main(void);
void bx_dbg_user_input_loop(void);
void bx_dbg_interpret_line(char *cmd);
typedef struct {
Bit16u sel;
Bit32u des_l, des_h, valid;
} bx_dbg_sreg_t;
typedef struct {
bx_address base;
Bit16u limit;
} bx_dbg_global_sreg_t;
typedef struct {
Bit32u eax;
Bit32u ebx;
Bit32u ecx;
Bit32u edx;
Bit32u ebp;
Bit32u esi;
Bit32u edi;
Bit32u esp;
Bit32u eflags;
Bit32u eip;
bx_dbg_sreg_t cs;
bx_dbg_sreg_t ss;
bx_dbg_sreg_t ds;
bx_dbg_sreg_t es;
bx_dbg_sreg_t fs;
bx_dbg_sreg_t gs;
bx_dbg_sreg_t ldtr;
bx_dbg_sreg_t tr;
struct { Bit32u base, limit; } gdtr;
struct { Bit32u base, limit; } idtr;
Bit32u dr0, dr1, dr2, dr3, dr6, dr7;
Bit32u cr0, cr1, cr2, cr3, cr4;
unsigned inhibit_mask;
} bx_dbg_cpu_t;
void bx_dbg_dma_report(Bit32u addr, unsigned len, unsigned what, Bit32u val);
void bx_dbg_iac_report(unsigned vector, unsigned irq);
void bx_dbg_a20_report(unsigned val);
void bx_dbg_io_report(Bit32u addr, unsigned size, unsigned op, Bit32u val);
void bx_dbg_ucmem_report(Bit32u addr, unsigned size, unsigned op, Bit32u val);
void bx_dbg_disassemble_current(int which_cpu, int print_time);
#endif // #ifdef __cplusplus
#endif // #if BX_DEBUGGER