2001-10-03 17:10:38 +04:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
2003-08-04 20:03:09 +04:00
|
|
|
// $Id: debug.h,v 1.19 2003-08-04 16:03:09 akrisak Exp $
|
2001-10-03 17:10:38 +04:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
2001-04-10 06:20:02 +04:00
|
|
|
// Copyright (C) 2001 MandrakeSoft S.A.
|
2001-04-10 05:04:59 +04:00
|
|
|
//
|
|
|
|
// 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"
|
2001-04-10 05:45:37 +04:00
|
|
|
#include "osdep.h"
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
#if BX_USE_LOADER
|
|
|
|
#include "loader_misc.h"
|
|
|
|
void bx_dbg_loader(char *path, bx_loader_misc_t *misc_ptr);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if BX_DBG_ICOUNT_SIZE == 32
|
|
|
|
typedef Bit32u bx_dbg_icount_t;
|
|
|
|
#elif BX_DBG_ICOUNT_SIZE == 64
|
|
|
|
typedef Bit64u bx_dbg_icount_t;
|
|
|
|
#else
|
|
|
|
# error "BX_DBG_ICOUNT_SIZE incorrect."
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#define BX_DBG_NO_HANDLE 1000
|
|
|
|
|
2001-05-23 12:16:07 +04:00
|
|
|
extern Bit32u dbg_cpu;
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
unsigned long crc32(unsigned char *buf, int len);
|
|
|
|
|
|
|
|
#if BX_DEBUGGER
|
|
|
|
|
|
|
|
// some strict C declarations needed by the parser/lexer
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2003-08-04 20:03:09 +04:00
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
rAL, rBL, rCL, rDL,
|
|
|
|
rAH, rBH, rCH, rDH,
|
|
|
|
rAX, rBX, rCX, rDX,
|
|
|
|
rEAX, rEBX, rECX, rEDX,
|
|
|
|
rSI, rDI, rESI, rEDI,
|
|
|
|
rBP, rEBP, rSP, rESP,
|
|
|
|
rIP, rEIP
|
|
|
|
} Regs;
|
|
|
|
|
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
bkRegular,
|
|
|
|
bkAtIP,
|
|
|
|
bkStepOver
|
|
|
|
} BreakpointKind;
|
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
// 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);
|
|
|
|
|
2001-05-23 12:16:07 +04:00
|
|
|
typedef struct {
|
|
|
|
Bit64s from;
|
|
|
|
Bit64s to;
|
|
|
|
} bx_num_range;
|
|
|
|
#define EMPTY_ARG (-1)
|
|
|
|
|
2003-08-04 20:03:09 +04:00
|
|
|
Bit16u bx_dbg_get_selector_value(unsigned int seg_no);
|
|
|
|
Bit32u bx_dbg_get_reg_value(Regs reg);
|
|
|
|
void bx_dbg_set_reg_value (Regs reg, Bit32u value);
|
|
|
|
Bit32u bx_dbg_get_laddr(Bit16u sel, Bit32u ofs);
|
|
|
|
void bx_dbg_step_over_command(void);
|
2001-05-23 12:16:07 +04:00
|
|
|
bx_num_range make_num_range (Bit64s from, Bit64s to);
|
2001-04-10 05:04:59 +04:00
|
|
|
char* bx_dbg_symbolic_address(Bit32u context, Bit32u eip, Bit32u base);
|
2003-08-04 20:03:09 +04:00
|
|
|
char* bx_dbg_disasm_symbolic_address(Bit32u eip, Bit32u base);
|
|
|
|
Bit32u bx_dbg_get_symbol_value(char *Symbol);
|
2002-10-25 15:44:41 +04:00
|
|
|
void bx_dbg_symbol_command(char* filename, bx_bool global, Bit32u offset);
|
2001-04-10 05:04:59 +04:00
|
|
|
void bx_dbg_trace_on_command(void);
|
|
|
|
void bx_dbg_trace_off_command(void);
|
2001-11-28 21:37:12 +03:00
|
|
|
void bx_dbg_trace_reg_on_command(void);
|
|
|
|
void bx_dbg_trace_reg_off_command(void);
|
2001-04-10 05:04:59 +04:00
|
|
|
void bx_dbg_ptime_command(void);
|
2002-10-25 15:44:41 +04:00
|
|
|
void bx_dbg_timebp_command(bx_bool absolute, Bit64u time);
|
2001-04-10 05:04:59 +04:00
|
|
|
void bx_dbg_diff_memory(void);
|
2002-10-25 15:44:41 +04:00
|
|
|
void bx_dbg_always_check(Bit32u page_start, bx_bool on);
|
|
|
|
void bx_dbg_sync_memory(bx_bool set);
|
|
|
|
void bx_dbg_sync_cpu(bx_bool set);
|
2001-04-10 05:04:59 +04:00
|
|
|
void bx_dbg_fast_forward(Bit32u num);
|
|
|
|
void bx_dbg_info_address(Bit32u seg_reg_num, Bit32u offset);
|
|
|
|
#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(char*); /* BW */
|
|
|
|
void bx_dbg_where_command(void);
|
|
|
|
void bx_dbg_print_string_command(Bit32u addr);
|
|
|
|
void bx_dbg_show_command(char*); /* BW */
|
2003-08-04 20:03:09 +04:00
|
|
|
void enter_playback_entry(void);
|
2001-04-10 05:04:59 +04:00
|
|
|
void bx_dbg_print_stack_command(int nwords);
|
2001-04-10 05:45:37 +04:00
|
|
|
void bx_dbg_watch(int read, Bit32u address);
|
|
|
|
void bx_dbg_unwatch(int read, Bit32u address);
|
2001-04-10 05:04:59 +04:00
|
|
|
void bx_dbg_continue_command(void);
|
|
|
|
void bx_dbg_stepN_command(bx_dbg_icount_t count);
|
|
|
|
void bx_dbg_set_command(char *p1, char *p2, char *p3);
|
|
|
|
void bx_dbg_del_breakpoint_command(unsigned handle);
|
2003-08-04 20:03:09 +04:00
|
|
|
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, Bit32u eip);
|
|
|
|
int bx_dbg_lbreakpoint_command(BreakpointKind bk, Bit32u laddress);
|
|
|
|
int bx_dbg_lbreakpoint_symbol_command(char *Symbol);
|
|
|
|
int bx_dbg_pbreakpoint_command(BreakpointKind bk, Bit32u paddress);
|
2001-04-10 05:04:59 +04:00
|
|
|
void bx_dbg_info_bpoints_command(void);
|
|
|
|
void bx_dbg_quit_command(void);
|
|
|
|
void bx_dbg_info_program_command(void);
|
2001-09-15 10:55:14 +04:00
|
|
|
#define BX_INFO_CPU_REGS 1 /* choices for bx_dbg_info_registers_command */
|
|
|
|
#define BX_INFO_FPU_REGS 2
|
|
|
|
void bx_dbg_info_registers_command(int);
|
2001-04-10 05:04:59 +04:00
|
|
|
void bx_dbg_info_dirty_command(void);
|
2001-05-23 12:16:07 +04:00
|
|
|
void bx_dbg_info_idt_command(bx_num_range);
|
|
|
|
void bx_dbg_info_gdt_command(bx_num_range);
|
|
|
|
void bx_dbg_info_ldt_command(bx_num_range);
|
|
|
|
void bx_dbg_info_tss_command(bx_num_range);
|
|
|
|
void bx_dbg_info_control_regs_command(void);
|
2003-08-04 20:03:09 +04:00
|
|
|
void bx_dbg_info_flags(void);
|
2001-05-23 12:16:07 +04:00
|
|
|
void bx_dbg_info_linux_command(void);
|
2003-08-04 20:03:09 +04:00
|
|
|
void bx_dbg_info_symbols_command(char *Symbol);
|
2002-10-25 15:44:41 +04:00
|
|
|
void bx_dbg_examine_command(char *command, char *format, bx_bool format_passed,
|
|
|
|
Bit32u addr, bx_bool addr_passed, int simulator);
|
2001-04-10 05:04:59 +04:00
|
|
|
void bx_dbg_setpmem_command(Bit32u addr, unsigned len, Bit32u val);
|
|
|
|
void bx_dbg_set_symbol_command(char *symbol, Bit32u val);
|
|
|
|
void bx_dbg_query_command(char *);
|
|
|
|
void bx_dbg_take_command(char *, unsigned n);
|
|
|
|
void bx_dbg_dump_cpu_command(void);
|
|
|
|
void bx_dbg_set_cpu_command(void);
|
2003-08-04 20:03:09 +04:00
|
|
|
void bx_dbg_disassemble_command(const char *,bx_num_range);
|
2001-04-10 05:04:59 +04:00
|
|
|
void bx_dbg_instrument_command(char *);
|
|
|
|
void bx_dbg_loader_command(char *);
|
|
|
|
void bx_dbg_doit_command(unsigned);
|
|
|
|
void bx_dbg_crc_command(Bit32u addr1, Bit32u addr2);
|
2002-10-25 15:44:41 +04:00
|
|
|
extern bx_bool watchpoint_continue;
|
2003-08-04 20:03:09 +04:00
|
|
|
void bx_dbg_linux_syscall (void);
|
2001-09-29 23:16:34 +04:00
|
|
|
void bx_dbg_info_ne2k(int page, int reg);
|
2003-08-04 20:03:09 +04:00
|
|
|
void bx_dbg_info_pic(void);
|
2002-10-04 18:57:36 +04:00
|
|
|
void bx_dbg_help_command(char* command);
|
2003-08-04 20:03:09 +04:00
|
|
|
void bx_dbg_calc_command(Bit64u value);
|
2003-08-01 14:14:48 +04:00
|
|
|
void bx_dbg_info_ivt_command(bx_num_range);
|
2001-04-10 05:04:59 +04:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// the rest for C++
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
|
|
|
// (mch) 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 {
|
2001-09-27 18:19:38 +04:00
|
|
|
STOP_NO_REASON = 0, STOP_TIME_BREAK_POINT, STOP_READ_WATCH_POINT, STOP_WRITE_WATCH_POINT, STOP_MAGIC_BREAK_POINT, UNUSED_STOP_TRACE, STOP_MODE_BREAK_POINT, STOP_CPU_HALTED
|
2001-04-10 05:04:59 +04:00
|
|
|
} stop_reason_t;
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
BREAK_POINT_MAGIC, BREAK_POINT_READ, BREAK_POINT_WRITE, BREAK_POINT_TIME
|
|
|
|
} break_point_t;
|
|
|
|
|
|
|
|
#define BX_DBG_REG_EAX 10
|
|
|
|
#define BX_DBG_REG_ECX 11
|
|
|
|
#define BX_DBG_REG_EDX 12
|
|
|
|
#define BX_DBG_REG_EBX 13
|
|
|
|
#define BX_DBG_REG_ESP 14
|
|
|
|
#define BX_DBG_REG_EBP 15
|
|
|
|
#define BX_DBG_REG_ESI 16
|
|
|
|
#define BX_DBG_REG_EDI 17
|
|
|
|
#define BX_DBG_REG_EIP 18
|
|
|
|
#define BX_DBG_REG_EFLAGS 19
|
|
|
|
#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_PENDING_DMA 1
|
|
|
|
#define BX_DBG_PENDING_IRQ 2
|
|
|
|
|
|
|
|
|
|
|
|
|
- add infrastructure for sending commands from the wxWindows interface to the
Bochs debugger. The Bochs debugger calls SIM->debug_get_next_command() which
does not return until a debugger command is found. The siminterface sends an
synchronous event to the wxWindows thread with a blank to be filled in with a
debugger command. wxWindows fills in the blank and sends the synchronous
event back, and the Bochs debugger interprets it as if it was typed on
the command line. For the long term I haven't decided whether to stick with
sending text strings vs. some other method.
- so far the wxWindows debugger consists of one big dialog box that shows
all the standard registers, and a working Continue, Stop, and Step button.
- modify ParamDialog so that it is more useful as a base class, by moving
some things to protected members&fields, separating out functionality
that is most likely to be replaced into virtual functions, and making it
generally more flexible. The new CpuRegistersDialog is based on
ParamDialog.
- in wxdialog.cc, continue the convention of using wxID_HELP, wxID_OK,
wxID_CANCEL, etc. for the id's of buttons, instead of wxHELP, wxOK, etc.
which are intended to be ORred together in a bit field.
- cpu/init.cc: put ifdefs around DEFPARAMs for flags in configurations
where they don't exist. Add an eflags shadow parameter that represents all
of the bits of eflags at once. There are also boolean shadow params for
each bit.
- modified files: cpu/init.cc debug/dbg_main.cc debug/debug.h
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h
2002-09-13 23:39:38 +04:00
|
|
|
void bx_debug_break ();
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
void bx_dbg_exit(int code);
|
|
|
|
#if BX_DBG_EXTENSIONS
|
|
|
|
int bx_dbg_extensions(char *command);
|
|
|
|
#else
|
|
|
|
#define bx_dbg_extensions(command) 0
|
|
|
|
#endif
|
|
|
|
|
- add Debug Log dialog, which shows all the text output that is normally
printed to stderr in the text debugger. Also allows the user to
type (text) debugger commands directly, which also appear in the log.
- all text output in the debugger now passes through dbg_printf()
(used to be fprintf to stderr) so that in wxWindows I can redirect
it all to the wxWindows debug log screen. Added debug_fputs to
siminterface which actually sends the text to the GUI by creating
a BX_ASYNC_EVT_DBG_MSG event.
- changed prefix and msg fields of BxLogMsgEvent to const char *,
and also in args of logmsg method of siminterface.
- don't trap SIGINT in wxWindows. There are other ways to stop execution.
Also, signal handling with multiple threads is very strange and different
on different platforms.
- minor changes to fix gcc -Wall warnings in dbg_main.cc
- add a new boolean parameter BXP_DEBUG_RUNNING that tells if the debugger is
running freely or not. This is used by the wxWindows GUI to enable or
disable certain choices.
- CpuRegistersDialog has continue,stop,step buttons. When the sim is running
freely, I disable continue and step, and enable stop. When the sim stops
to wait for the user, I disable stop and enable continue and step. The
change of enables used to be triggered by actually pressing the button,
but then if you started/stopped the simulation in some other way (typing
in debug log window) the enables were never changed. Now the enables are
controlled by the value of BXP_DEBUG_RUNNING, which is set by the debug code
itself, and the buttons are enabled at the right time.
- ParamDialog::Refresh() is now virtual so that child classes can redefine
its refresh behavior.
- in safeWxStrcpy, force the last element of the array to be a 0, since
I noticed that strncpy is not guaranteed to terminate the string!
- modified: debug/dbg_main.cc debug/debug.h gui/siminterface.cc
gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc
gui/wxmain.h
2002-09-15 15:21:35 +04:00
|
|
|
void dbg_printf (const char *fmt, ...);
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
//
|
|
|
|
// code for guards...
|
|
|
|
//
|
|
|
|
|
|
|
|
#define BX_DBG_GUARD_INSTR_BEGIN 0x0001
|
|
|
|
#define BX_DBG_GUARD_INSTR_END 0x0002
|
|
|
|
#define BX_DBG_GUARD_EXCEP_BEGIN 0x0004
|
|
|
|
#define BX_DBG_GUARD_EXCEP_END 0x0008
|
|
|
|
#define BX_DBG_GUARD_INTER_BEGIN 0x0010
|
|
|
|
#define BX_DBG_GUARD_INTER_END 0x0020
|
|
|
|
#define BX_DBG_GUARD_INSTR_MAP 0x0040
|
|
|
|
|
|
|
|
// following 3 go along with BX_DBG_GUARD_INSTR_BEGIN
|
|
|
|
// to provide breakpointing
|
|
|
|
#define BX_DBG_GUARD_IADDR_VIR 0x0080
|
|
|
|
#define BX_DBG_GUARD_IADDR_LIN 0x0100
|
|
|
|
#define BX_DBG_GUARD_IADDR_PHY 0x0200
|
|
|
|
#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 0x0400
|
|
|
|
#define BX_DBG_GUARD_CTRL_C 0x0800
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
Bit32u eip;
|
|
|
|
unsigned bpoint_id;
|
2003-08-04 20:03:09 +04:00
|
|
|
bx_bool enabled;
|
2001-04-10 05:04:59 +04:00
|
|
|
} vir[BX_DBG_MAX_VIR_BPOINTS];
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if BX_DBG_SUPPORT_LIN_BPOINT
|
|
|
|
unsigned num_linear;
|
|
|
|
struct {
|
|
|
|
Bit32u addr;
|
|
|
|
unsigned bpoint_id;
|
2003-08-04 20:03:09 +04:00
|
|
|
bx_bool enabled;
|
2001-04-10 05:04:59 +04:00
|
|
|
} lin[BX_DBG_MAX_LIN_BPOINTS];
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if BX_DBG_SUPPORT_PHY_BPOINT
|
|
|
|
unsigned num_physical;
|
|
|
|
struct {
|
|
|
|
Bit32u addr;
|
|
|
|
unsigned bpoint_id;
|
2003-08-04 20:03:09 +04:00
|
|
|
bx_bool enabled;
|
2001-04-10 05:04:59 +04:00
|
|
|
} phy[BX_DBG_MAX_PHY_BPOINTS];
|
|
|
|
#endif
|
|
|
|
} iaddr;
|
|
|
|
|
|
|
|
bx_dbg_icount_t icount; // stop after completing this many instructions
|
|
|
|
|
|
|
|
// user typed Ctrl-C, requesting simulator stop at next convient spot
|
2002-10-25 15:44:41 +04:00
|
|
|
volatile bx_bool interrupt_requested;
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2002-03-12 12:16:41 +03:00
|
|
|
// when a triple fault occurs, Bochs panics. If you continue through
|
|
|
|
// the panic, it will generally produce another exception and panic
|
|
|
|
// again at an even deeper stack level. To recover from this potentially
|
|
|
|
// infinite recursion, I set special_unwind_stack to true. This causes
|
|
|
|
// the interrupt() and exception() functions to return immediately instead
|
|
|
|
// of creating more exception conditions, and allows the user to reenter the
|
|
|
|
// debugger after the triple fault. Note that special_unwind_stack causes
|
|
|
|
// bochs to NOT emulate the hardware behavior correctly. The correct
|
|
|
|
// behavior would be to reboot. (Rebooting, if it is ever implemented,
|
|
|
|
// will need some kind of unwinding too.)
|
2002-10-25 15:44:41 +04:00
|
|
|
bx_bool special_unwind_stack;
|
2002-03-12 12:16:41 +03:00
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
// booleans to control whether simulator should report events
|
|
|
|
// to debug controller
|
|
|
|
struct {
|
2002-10-25 15:44:41 +04:00
|
|
|
bx_bool irq;
|
|
|
|
bx_bool a20;
|
|
|
|
bx_bool io;
|
|
|
|
bx_bool ucmem;
|
|
|
|
bx_bool dma;
|
2001-04-10 05:04:59 +04:00
|
|
|
} report;
|
|
|
|
|
|
|
|
struct {
|
2002-10-25 15:44:41 +04:00
|
|
|
bx_bool irq; // should process IRQs asynchronously
|
|
|
|
bx_bool dma; // should process DMAs asynchronously
|
2001-04-10 05:04:59 +04:00
|
|
|
} 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
|
2002-10-25 15:44:41 +04:00
|
|
|
bx_bool a20;
|
|
|
|
bx_bool reset;
|
|
|
|
bx_bool nmi;
|
2001-04-10 05:04:59 +04:00
|
|
|
} async_changes_pending;
|
|
|
|
} bx_guard_t;
|
|
|
|
|
|
|
|
// working information for each simulator to update when a guard
|
|
|
|
// is reached (found)
|
2001-05-23 12:16:07 +04:00
|
|
|
typedef struct bx_guard_found_t {
|
2001-04-10 05:04:59 +04:00
|
|
|
unsigned long guard_found;
|
|
|
|
unsigned iaddr_index;
|
|
|
|
bx_dbg_icount_t icount; // number of completed instructions
|
|
|
|
Bit32u cs; // cs:eip and linear addr of instruction at guard point
|
|
|
|
Bit32u eip;
|
|
|
|
Bit32u laddr;
|
2002-10-25 15:44:41 +04:00
|
|
|
bx_bool is_32bit_code; // CS seg size at guard point
|
|
|
|
bx_bool ctrl_c; // simulator stopped due to Ctrl-C request
|
2001-04-10 05:04:59 +04:00
|
|
|
} bx_guard_found_t;
|
|
|
|
|
|
|
|
extern bx_guard_t bx_guard;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int bx_dbg_main(int argc, char *argv[]);
|
|
|
|
void bx_dbg_user_input_loop(void);
|
- add infrastructure for sending commands from the wxWindows interface to the
Bochs debugger. The Bochs debugger calls SIM->debug_get_next_command() which
does not return until a debugger command is found. The siminterface sends an
synchronous event to the wxWindows thread with a blank to be filled in with a
debugger command. wxWindows fills in the blank and sends the synchronous
event back, and the Bochs debugger interprets it as if it was typed on
the command line. For the long term I haven't decided whether to stick with
sending text strings vs. some other method.
- so far the wxWindows debugger consists of one big dialog box that shows
all the standard registers, and a working Continue, Stop, and Step button.
- modify ParamDialog so that it is more useful as a base class, by moving
some things to protected members&fields, separating out functionality
that is most likely to be replaced into virtual functions, and making it
generally more flexible. The new CpuRegistersDialog is based on
ParamDialog.
- in wxdialog.cc, continue the convention of using wxID_HELP, wxID_OK,
wxID_CANCEL, etc. for the id's of buttons, instead of wxHELP, wxOK, etc.
which are intended to be ORred together in a bit field.
- cpu/init.cc: put ifdefs around DEFPARAMs for flags in configurations
where they don't exist. Add an eflags shadow parameter that represents all
of the bits of eflags at once. There are also boolean shadow params for
each bit.
- modified files: cpu/init.cc debug/dbg_main.cc debug/debug.h
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h
2002-09-13 23:39:38 +04:00
|
|
|
void bx_dbg_interpret_line (char *cmd);
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
Bit16u sel;
|
|
|
|
Bit32u des_l, des_h, valid;
|
|
|
|
} bx_dbg_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 tr3, tr4, tr5, tr6, tr7;
|
|
|
|
Bit32u cr0, cr1, cr2, cr3, cr4;
|
|
|
|
unsigned inhibit_mask;
|
|
|
|
} bx_dbg_cpu_t;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
// call back functions specific to each simulator
|
2002-10-25 15:44:41 +04:00
|
|
|
bx_bool (*setphymem)(Bit32u addr, unsigned len, Bit8u *buf);
|
|
|
|
bx_bool (*getphymem)(Bit32u addr, unsigned len, Bit8u *buf);
|
|
|
|
void (*xlate_linear2phy)(Bit32u linear, Bit32u *phy, bx_bool *valid);
|
|
|
|
bx_bool (*set_reg)(unsigned reg, Bit32u val);
|
2001-04-10 05:04:59 +04:00
|
|
|
Bit32u (*get_reg)(unsigned reg);
|
2002-10-25 15:44:41 +04:00
|
|
|
bx_bool (*get_sreg)(bx_dbg_sreg_t *sreg, unsigned sreg_no);
|
|
|
|
bx_bool (*set_cpu)(bx_dbg_cpu_t *cpu);
|
|
|
|
bx_bool (*get_cpu)(bx_dbg_cpu_t *cpu);
|
2001-04-10 05:04:59 +04:00
|
|
|
unsigned dirty_page_tbl_size;
|
|
|
|
unsigned char *dirty_page_tbl;
|
|
|
|
void (*atexit)(void);
|
|
|
|
unsigned (*query_pending)(void);
|
|
|
|
void (*execute)(void);
|
|
|
|
void (*take_irq)(void);
|
|
|
|
void (*take_dma)(void);
|
|
|
|
void (*reset_cpu)(unsigned source);
|
|
|
|
void (*init_mem)(int size_in_bytes);
|
2003-04-02 21:03:34 +04:00
|
|
|
void (*load_ROM)(const char *path, Bit32u romaddress, Bit8u type);
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
// for asynchronous environment handling
|
|
|
|
void (*set_A20)(unsigned val);
|
|
|
|
void (*set_NMI)(unsigned val);
|
|
|
|
void (*set_RESET)(unsigned val);
|
|
|
|
void (*set_INTR)(unsigned val);
|
|
|
|
void (*force_interrupt)(unsigned vector);
|
|
|
|
|
|
|
|
#if BX_INSTRUMENTATION
|
|
|
|
void (*instr_start)(void);
|
|
|
|
void (*instr_stop)(void);
|
|
|
|
void (*instr_reset)(void);
|
|
|
|
void (*instr_print)(void);
|
|
|
|
#endif
|
|
|
|
#if BX_USE_LOADER
|
|
|
|
void (*loader)(char *path, bx_loader_misc_t *misc_ptr);
|
|
|
|
#endif
|
2002-10-25 15:44:41 +04:00
|
|
|
bx_bool (*crc32)(unsigned long (*f)(unsigned char *buf, int len),
|
2001-04-10 05:04:59 +04:00
|
|
|
Bit32u addr1, Bit32u addr2, Bit32u *crc);
|
|
|
|
} bx_dbg_callback_t;
|
|
|
|
|
2001-05-23 12:16:07 +04:00
|
|
|
extern bx_dbg_callback_t bx_dbg_callback[BX_NUM_SIMULATORS];
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
void BX_SIM1_INIT(bx_dbg_callback_t *, int argc, char *argv[]);
|
|
|
|
#ifdef BX_SIM2_INIT
|
|
|
|
void BX_SIM2_INIT(bx_dbg_callback_t *, int argc, char *argv[]);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
Bit8u bx_dbg_ucmem_read(Bit32u addr);
|
|
|
|
void bx_dbg_ucmem_write(Bit32u addr, Bit8u value);
|
2002-10-25 15:44:41 +04:00
|
|
|
void bx_dbg_async_pin_request(unsigned what, bx_bool val);
|
|
|
|
void bx_dbg_async_pin_ack(unsigned what, bx_bool val);
|
2001-04-10 05:04:59 +04:00
|
|
|
Bit32u bx_dbg_inp(Bit16u addr, unsigned len);
|
|
|
|
void bx_dbg_outp(Bit16u addr, Bit32u value, unsigned len);
|
|
|
|
void bx_dbg_raise_HLDA(void);
|
|
|
|
Bit8u bx_dbg_IAC(void);
|
2002-10-25 15:44:41 +04:00
|
|
|
void bx_dbg_set_INTR(bx_bool b);
|
2001-10-06 01:03:53 +04:00
|
|
|
void bx_dbg_disassemble_current (int which_cpu, int print_time);
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
int bx_dbg_symbolic_output(void); /* BW */
|
|
|
|
#endif // #ifdef __cplusplus
|
|
|
|
#endif // #if BX_DEBUGGER
|