File: debug.h

package info (click to toggle)
bochs 3.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 25,244 kB
  • sloc: cpp: 270,331; ansic: 25,334; sh: 8,371; makefile: 5,512; yacc: 1,485; asm: 395; perl: 359; lex: 318; csh: 3
file content (355 lines) | stat: -rw-r--r-- 12,837 bytes parent folder | download
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