1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355
|
/////////////////////////////////////////////////////////////////////////
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2024 The Bochs Project
//
// 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#ifndef BX_DEBUG_H
#define BX_DEBUG_H
// if including from C parser, need basic types etc
#include "config.h"
#include "osdep.h"
#define BX_DBG_NO_HANDLE 1000
Bit32u crc32(const Bit8u *buf, int len);
#if BX_DEBUGGER
#include "cpu/decoder/decoder.h"
// some strict C declarations needed by the parser/lexer
#ifdef __cplusplus
extern Bit32u dbg_cpu;
BOCHSAPI_MSVCONLY void dbg_printf(const char *fmt, ...);
typedef enum
{
bkRegular,
bkAtIP,
bkStepOver
} BreakpointKind;
extern "C" {
// Flex defs
extern int bxlex(void);
extern char *bxtext; // Using the pointer option rather than array
extern int bxwrap(void);
extern void bx_add_lex_input(char *buf);
// Yacc defs
extern int bxparse(void);
extern void bxerror(const char *s);
};
// register function for 'info device' command
BOCHSAPI_MSVCONLY bool bx_dbg_register_debug_info(const char *devname, void *dev);
#define EMPTY_ARG (-1)
void bx_dbg_addlyt(const char* new_layoutpath);
void bx_dbg_remlyt(void);
void bx_dbg_lyt(void);
void bx_dbg_set_magic_bp_mask(Bit8u new_mask);
void bx_dbg_clr_magic_bp_mask(Bit8u mask);
Bit8u bx_dbg_get_magic_bp_mask_from_str(const char *str);
void bx_dbg_print_magic_bp_mask_from_str(Bit8u mask);
bool bx_dbg_read_linear(unsigned which_cpu, bx_address laddr, unsigned len, Bit8u *buf);
bool bx_dbg_write_linear(unsigned which_cpu, bx_address laddr, unsigned len, Bit8u *buf);
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_rip(void);
bx_address bx_dbg_get_ssp(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);
Bit64u bx_dbg_get_opmask_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);
void bx_dbg_set_rip_value(bx_address value);
void bx_dbg_load_segreg(unsigned reg, unsigned value);
bx_address bx_dbg_get_laddr(Bit16u sel, bx_address ofs);
void bx_dbg_step_over_command(void);
void bx_dbg_trace_command(bool enable);
void bx_dbg_trace_reg_command(bool enable);
void bx_dbg_trace_mem_command(bool enable);
void bx_dbg_ptime_command(void);
void bx_dbg_timebp_command(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_modebp_command(void);
void bx_dbg_vmexitbp_command(void);
void bx_dbg_where_command(void);
void bx_dbg_print_string_command(bx_address addr);
void bx_dbg_xlate_address(bx_lin_address laddr);
void bx_dbg_tlb_lookup(bx_lin_address laddr);
void bx_dbg_show_command(const char*);
void bx_dbg_print_stack_command(unsigned nwords);
void bx_dbg_deref_command(bx_address addr, unsigned deep);
bx_address bx_dbg_deref(bx_address addr, unsigned deep, unsigned* error_deep, bx_address* last_data_found);
void bx_dbg_bt_command(unsigned dist);
void bx_dbg_print_watchpoints(void);
void bx_dbg_watchpoint_continue(bool watch_continue);
void bx_dbg_watch(int type, bx_phy_address address, Bit32u len);
void bx_dbg_unwatch_all(void);
void bx_dbg_unwatch(bx_phy_address handle);
void bx_dbg_continue_command(bool expression);
void bx_dbg_stepN_command(int cpu, Bit32u count);
void bx_dbg_set_auto_disassemble(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, bool enable);
bool bx_dbg_en_dis_pbreak(unsigned handle, bool enable);
bool bx_dbg_en_dis_lbreak(unsigned handle, bool enable);
bool bx_dbg_en_dis_vbreak(unsigned handle, bool enable);
bool bx_dbg_del_pbreak(unsigned handle);
bool bx_dbg_del_lbreak(unsigned handle);
bool bx_dbg_del_vbreak(unsigned handle);
int bx_dbg_vbreakpoint_command(BreakpointKind bk, Bit32u cs, bx_address eip, const char *condition);
int bx_dbg_lbreakpoint_command(BreakpointKind bk, bx_address laddress, const char *condition);
int bx_dbg_pbreakpoint_command(BreakpointKind bk, bx_phy_address paddress, const char *condition);
void bx_dbg_info_bpoints_command(void);
void bx_dbg_quit_command(void);
#define BX_INFO_GENERAL_PURPOSE_REGS 0x01 /* bitmasks - choices for bx_dbg_info_registers_command */
#define BX_INFO_FPU_REGS 0x02
#define BX_INFO_MMX_REGS 0x04
#define BX_INFO_SSE_REGS 0x08
#define BX_INFO_YMM_REGS 0x10
#define BX_INFO_ZMM_REGS 0x20
#define BX_INFO_AMX_REGS 0x40
void bx_dbg_info_registers_command(int);
void bx_dbg_print_amx_tile_command(int tile);
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_debug_regs_command(void);
void bx_dbg_info_control_regs_command(void);
void bx_dbg_info_segment_regs_command(void);
void bx_dbg_info_flags(void);
void bx_dbg_info_linux_command(void);
void bx_dbg_examine_command(const char *command, const char *format, bool format_passed,
bx_address addr, bool addr_passed);
Bit32u bx_dbg_lin_indirect(bx_address addr);
Bit32u bx_dbg_phy_indirect(bx_phy_address addr);
void bx_dbg_writemem_command(const char *filename, bx_address laddr, unsigned len);
void bx_dbg_loadmem_command(const char *filename, bx_address laddr);
void bx_dbg_setpmem_command(bx_phy_address addr, unsigned len, Bit64u val);
void bx_dbg_query_command(const char *);
void bx_dbg_take_command(const char *, unsigned n);
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(bx_phy_address addr1, bx_phy_address addr2);
void bx_dbg_linux_syscall(unsigned which_cpu);
void bx_dbg_info_device(const char *, const char *);
void bx_dbg_print_help(void);
void bx_dbg_calc_command(Bit64u value);
void bx_dbg_dump_table(void);
bool bx_dbg_eval_condition(char *condition);
// callbacks from CPU
void bx_dbg_exception(unsigned cpu, Bit8u vector, Bit16u error_code);
void bx_dbg_interrupt(unsigned cpu, Bit8u vector, Bit16u error_code);
void bx_dbg_halt(unsigned cpu);
// memory trace callbacks from CPU
void bx_dbg_lin_memory_access(unsigned cpu, bx_address lin, bx_phy_address phy, unsigned len, unsigned memtype, unsigned rw, Bit8u *data);
void bx_dbg_phy_memory_access(unsigned cpu, bx_phy_address phy, unsigned len, unsigned memtype, unsigned rw, unsigned attr, Bit8u *data);
// check memory access for watchpoints
void bx_dbg_check_memory_watchpoints(unsigned cpu, bx_phy_address phy, unsigned len, unsigned rw);
// commands that work with Bochs param tree
void bx_dbg_restore_command(const char *param_name, const char *path);
void bx_dbg_show_param_command(const char *param, bool xml);
void bx_dbg_show_symbolic(void);
void bx_dbg_set_symbol_command(const char *symbol, bx_address val);
const char* bx_dbg_symbolic_address(bx_address context, bx_address eip, bx_address base);
int bx_dbg_symbol_command(const char* filename, bool global, bx_address offset);
void bx_dbg_info_symbols_command(const char *Symbol);
int bx_dbg_lbreakpoint_symbol_command(const char *Symbol, const char *condition);
bx_address bx_dbg_get_symbol_value(const char *Symbol);
const char* bx_dbg_disasm_symbolic_address(bx_address eip, bx_address base);
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_VMEXIT_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_PENDING_DMA 1
#define BX_DBG_PENDING_IRQ 2
BOCHSAPI_MSVCONLY void bx_debug_break(void);
BOCHSAPI_MSVCONLY 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_ICOUNT 0x0010
struct bx_guard_t {
unsigned guard_for;
// instruction address breakpoints
struct ibreak {
#if (BX_DBG_MAX_VIR_BPOINTS > 0)
unsigned num_virtual;
struct vbreak {
Bit32u cs; // only use 16 bits
bx_address eip;
unsigned bpoint_id;
bool enabled;
char *condition;
} vir[BX_DBG_MAX_VIR_BPOINTS];
#endif
#if (BX_DBG_MAX_LIN_BPOINTS > 0)
unsigned num_linear;
struct lbreak {
bx_address addr;
unsigned bpoint_id;
bool enabled;
char *condition;
} lin[BX_DBG_MAX_LIN_BPOINTS];
#endif
#if (BX_DBG_MAX_PHY_BPOINTS > 0)
unsigned num_physical;
struct pbreak {
bx_phy_address addr;
unsigned bpoint_id;
bool enabled;
char *condition;
} phy[BX_DBG_MAX_PHY_BPOINTS];
#endif
} iaddr;
// user typed Ctrl-C, requesting simulator stop at next convinient spot
volatile bool interrupt_requested;
// booleans to control whether simulator should report events
// to debug controller
struct {
bool irq;
bool a20;
bool io;
bool dma;
} report;
struct {
bool irq; // should process IRQs asynchronously
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
bool a20;
bool reset;
bool nmi;
} async_changes_pending;
};
struct bx_watchpoint {
bx_phy_address addr;
Bit32u len;
};
extern unsigned num_write_watchpoints;
extern unsigned num_read_watchpoints;
extern bx_watchpoint write_watchpoint[BX_DBG_MAX_WATCHPONTS];
extern bx_watchpoint read_watchpoint[BX_DBG_MAX_WATCHPONTS];
BOCHSAPI_MSVCONLY extern bx_guard_t bx_guard;
#define IS_CODE_32(code_32_64) ((code_32_64 & 1) != 0)
#define IS_CODE_64(code_32_64) ((code_32_64 & 2) != 0)
void bx_dbg_init(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 bx_dbg_sreg_t {
Bit16u sel;
Bit32u des_l, des_h, valid;
#if BX_SUPPORT_X86_64
Bit32u dword3;
#endif
} bx_dbg_sreg_t;
BOCHSAPI_MSVCONLY void bx_dbg_dma_report(bx_phy_address addr, unsigned len, unsigned what, Bit32u val);
BOCHSAPI_MSVCONLY void bx_dbg_iac_report(unsigned vector, unsigned irq);
void bx_dbg_a20_report(unsigned val);
void bx_dbg_io_report(Bit32u port, unsigned size, unsigned op, Bit32u val);
void bx_dbg_disassemble_current(int which_cpu, int print_time);
unsigned bx_dbg_disasm_wrapper(bool is_32, bool is_64, bx_address cs_base, bx_address ip, const Bit8u *instr, char *disbuf, int intel_disasm_style = -1);
#endif // #ifdef __cplusplus
#endif // #if BX_DEBUGGER
#endif
|