00001
00002
00003 #ifndef jdb_h
00004 #define jdb_h
00005
00006 #include "l4_types.h"
00007 #include "pic.h"
00008
00009 #include "jdb_core.h"
00010 #include "jdb_handler_queue.h"
00011 #include "trap_state.h"
00012
00013
00014
00015
00016
00017
00018 class Trap_state;
00019 class Thread;
00020 class Console_buffer;
00021 class Jdb_entry_frame;
00022
00023 class Space;
00024 class Thread;
00025
00026 class Space;
00027
00028
00029
00030
00031
00032 class Jdb
00033
00034 : public Jdb_core
00035 {
00036 public:
00037 static void init();
00038
00039 static Pic::Status pic_status;
00040 static const char * const reg_names[];
00041 static char lbr_active;
00042 static volatile char test_msr;
00043
00044 typedef enum
00045 {
00046 s_unknown, s_ipc, s_syscall, s_pagefault, s_fputrap,
00047 s_interrupt, s_timer_interrupt, s_slowtrap, s_user_invoke,
00048 } Guessed_thread_state;
00049
00050 template < typename T > static T peek(T const *addr, Address_type user);
00051
00052 static int (*bp_test_log_only)();
00053 static int (*bp_test_sstep)();
00054 static int (*bp_test_break)(char *errbuf, size_t bufsize);
00055 static int (*bp_test_other)(char *errbuf, size_t bufsize);
00056
00057 private:
00058 Jdb();
00059 Jdb(const Jdb&);
00060
00061 template < typename T > static T peek(T const *addr);
00062
00063 struct Traps
00064 {
00065 char const *name;
00066 char error_code;
00067 };
00068
00069 static Traps const traps[20];
00070 static char error_buffer[81];
00071
00072 static Mword gdb_trap_ip;
00073 static Mword gdb_trap_pfa;
00074 static Mword gdb_trap_no;
00075 static Mword gdb_trap_err;
00076 static unsigned old_phys_pte;
00077
00078 static char _connected;
00079 static char was_input_error;
00080 static char permanent_single_step;
00081 static char hide_statline;
00082 static char use_nested;
00083 static char jdb_trap_recover;
00084 static char code_ret, code_call, code_bra, code_int;
00085
00086 static const char *toplevel_cmds;
00087 static const char *non_interactive_cmds;
00088
00089 typedef enum
00090 {
00091 SS_NONE=0, SS_BRANCH, SS_RETURN
00092 } Step_state;
00093
00094 static Step_state ss_state;
00095 static int ss_level;
00096
00097 static const Unsigned8 *debug_ctrl_str;
00098 static int debug_ctrl_len;
00099
00100 static int jdb_irqs_disabled;
00101
00102 public:
00103 static char esc_iret[];
00104 static char esc_bt[];
00105 static char esc_emph[];
00106 static char esc_emph2[];
00107 static char esc_mark[];
00108 static char esc_line[];
00109 static char esc_symbol[];
00110 private:
00111
00112 public:
00113 enum
00114 {
00115 NOFANCY=0,
00116 FANCY=1
00117 };
00118 private:
00119
00120 public:
00121 static void printf_statline (const char *prompt, const char *help,
00122 const char *format, ...)
00123 __attribute__((format(printf, 3, 4)));
00124
00125 static int getchar(void);
00126 static int was_last_cmd(void);
00127 static int get_next_cmd(void);
00128 static void set_next_cmd(char c);
00129 static void flush_next_cmd(void);
00130 static bool is_toplevel_cmd(char c);
00131
00132 static Jdb_handler_queue jdb_enter;
00133 static Jdb_handler_queue jdb_leave;
00134
00135 private:
00136 static Thread *current_active;
00137 static char last_cmd;
00138 static char next_cmd;
00139 static Trap_state::Handler nested_trap_handler FIASCO_FASTCALL;
00140 static Jdb_entry_frame *entry_frame;
00141 private:
00142
00143 public:
00148 static Thread *get_thread();
00149
00150 public:
00151 static inline bool connected();
00152
00153 static inline int source_level_debugging();
00154
00155
00156
00157 static void abort_command();
00158
00159 static int get_register(char *reg);
00160
00161 static Address establish_phys_mapping(Address phys, Address *offs);
00162
00163 static Task_num translate_task(Address addr, Task_num task);
00164
00165 static int peek_phys(Address phys);
00166
00167 static int poke_phys(Address phys, Unsigned8 value);
00168
00169 static int peek_task(Address addr, Task_num task);
00170
00171 static int poke_task(Address addr, Task_num task, Unsigned8 value);
00172
00173 static int peek_mword_task(Address addr, Task_num task, Mword *result);
00174
00175 static int peek_addr_task(Address virt, Task_num task, Address *result);
00176
00177 static void poke_mword_task(Address virt, Task_num task, Mword value);
00178
00179 static int is_adapter_memory(Address addr, Task_num task);
00180
00181
00182
00183 static Jdb::Guessed_thread_state guess_thread_state(Thread *t);
00184
00185 static void set_single_step(int on);
00186
00187 static inline void enter_getchar();
00188
00189 static inline void leave_getchar();
00190
00191 static void cursor(unsigned int row=0, unsigned int col=0);
00192
00193 static inline void blink_cursor(unsigned int row, unsigned int col);
00194
00195 static inline void cursor_save();
00196
00197 static inline void cursor_restore();
00198
00199 static inline void screen_erase();
00200
00201 static void screen_scroll(unsigned int start, unsigned int end);
00202
00203 static inline void clear_to_eol();
00204
00205
00206 static void clear_screen(int fancy=FANCY);
00207
00208
00209 static int std_cursor_key(int c, Mword cols, Mword lines, Mword max_absy, Mword *absy, Mword *addy, Mword *addx, bool *redraw);
00210
00211 static int execute_command(const char *s, int first_char = -1);
00212
00213 static void write_ll_ns(Signed64 ns, char *buf, int maxlen, bool sign);
00214
00215 static void write_tsc_s(Signed64 tsc, char *buf, int maxlen, bool sign);
00216
00217 static void write_tsc(Signed64 tsc, char *buf, int maxlen, bool sign);
00218
00219 static void write_ll_hex(Signed64 x, char *buf, int maxlen, bool sign);
00220
00221 static void write_ll_dec(Signed64 x, char *buf, int maxlen, bool sign);
00222
00223 static inline Thread* get_current_active();
00224
00225 static inline Jdb_entry_frame* get_entry_frame();
00226
00227 static int is_valid_task(Task_num task);
00228
00229 static Space* lookup_space(Task_num task);
00230
00231 static void get_current();
00232
00233 static inline Space* get_current_space();
00234
00235 static inline Task_num get_current_task();
00236
00237 private:
00238 static inline void backspace();
00239
00240
00241 static void save_disable_irqs();
00242
00243
00244 static void restore_irqs();
00245
00246
00247 static void open_debug_console();
00248
00249 static void close_debug_console();
00250
00251 static int switch_debug_state();
00252
00253
00254 static int execute_command();
00255
00256
00257
00258
00259 static void analyze_code();
00260
00261
00262 static inline int handle_single_step();
00263
00264
00265 static inline int handle_trap1();
00266
00267
00268 static inline int handle_trap3();
00269
00270
00271 static inline int handle_trapX();
00272
00277 static inline int handle_int3();
00278
00279 static inline void enable_lbr();
00280
00281 static FIASCO_FASTCALL int enter_kdebugger(Trap_state *ts);
00282
00283
00284
00285 static int execute_command_ni(Unsigned8 const *str, int len=0);
00286
00293 static int handle_int3_threadctx(Trap_state *ts);
00294
00301 static int handle_int3_threadctx_generic(Trap_state *ts);
00302 };
00303
00304
00305
00306
00307
00308
00309 class Jdb_entry_frame : public Trap_state
00310 {
00311 public:
00312 inline Address_type from_user();
00313
00314 inline Address get_ksp();
00315
00316 inline Address _get_esp();
00317
00318 inline Mword param();
00319
00320 inline Mword _get_ss();
00321 };
00322
00323
00324
00325
00326
00327
00328 #include <flux/x86/gdb.h>
00329
00330 #include <cstring>
00331 #include <csetjmp>
00332 #include <cstdarg>
00333 #include <climits>
00334 #include <cstdlib>
00335 #include <cstdio>
00336 #include "simpleio.h"
00337
00338 #include "boot_info.h"
00339 #include "checksum.h"
00340 #include "cmdline.h"
00341 #include "config.h"
00342 #include "cpu.h"
00343 #include "initcalls.h"
00344 #include "idt.h"
00345 #include "jdb_core.h"
00346 #include "jdb_tbuf_init.h"
00347 #include "jdb_screen.h"
00348 #include "kernel_console.h"
00349 #include "keycodes.h"
00350 #include "kernel_uart.h"
00351 #include "kmem.h"
00352 #include "logdefs.h"
00353 #include "mem_layout.h"
00354 #include "pic.h"
00355 #include "push_console.h"
00356 #include "processor.h"
00357 #include "regdefs.h"
00358 #include "static_init.h"
00359 #include "terminate.h"
00360 #include "thread.h"
00361 #include "thread_state.h"
00362 #include "timer.h"
00363 #include "trap_state.h"
00364 #include "virq.h"
00365 #include "vkey.h"
00366 #include "watchdog.h"
00367
00368 #include <cstdio>
00369 #include <simpleio.h>
00370 #include "jdb_screen.h"
00371
00372 #include "config.h"
00373 #include "div32.h"
00374 #include "kernel_console.h"
00375 #include "paging.h"
00376
00377 #include "jdb_prompt_ext.h"
00378 #include "jdb.h"
00379 #include "thread.h"
00380
00381 #include "space_index.h"
00382
00383 #include "jdb.h"
00384 #include "thread.h"
00385
00386 #include "profile.h"
00387 #include "thread.h"
00388
00389 #include "jdb_dbinfo.h"
00390 #include "jdb_lines.h"
00391 #include "jdb_symbol.h"
00392 #include "jdb_tbuf.h"
00393 #include "jdb_thread_names.h"
00394 #include "thread.h"
00395 #include "timer.h"
00396
00397
00398
00399
00400
00401
00402
00403 inline bool
00404 Jdb::connected()
00405 {
00406 return _connected;
00407 }
00408
00409
00410 inline int
00411 Jdb::source_level_debugging()
00412 {
00413 return use_nested;
00414 }
00415
00416
00417
00418 inline void
00419 Jdb::enter_getchar()
00420 {}
00421
00422
00423
00424 inline void
00425 Jdb::leave_getchar()
00426 {}
00427
00428
00429
00430 inline void
00431 Jdb::blink_cursor(unsigned int row, unsigned int col)
00432 {
00433 printf ("\033[%d;%df", row, col);
00434 }
00435
00436
00437
00438 inline void
00439 Jdb::cursor_save()
00440 {
00441 putstr ("\0337");
00442 }
00443
00444
00445
00446 inline void
00447 Jdb::cursor_restore()
00448 {
00449 putstr ("\0338");
00450 }
00451
00452
00453
00454 inline void
00455 Jdb::screen_erase()
00456 {
00457 putstr ("\033[2J");
00458 }
00459
00460
00461
00462 inline void
00463 Jdb::clear_to_eol()
00464 {
00465 putstr("\033[K");
00466 }
00467
00468
00469
00470 inline Thread*
00471 Jdb::get_current_active()
00472 {
00473 return current_active;
00474 }
00475
00476
00477
00478 inline Jdb_entry_frame*
00479 Jdb::get_entry_frame()
00480 {
00481 return entry_frame;
00482 }
00483
00484
00485
00486 inline Space*
00487 Jdb::get_current_space()
00488 {
00489 return current_active ? current_active->space() : 0;
00490 }
00491
00492
00493
00494 inline Task_num
00495 Jdb::get_current_task()
00496 {
00497 return current_active ? current_active->id().task() : 0;
00498 }
00499
00500
00501
00502 template <typename T> inline T
00503 Jdb::peek(T const *addr, Address_type)
00504 {
00505
00506 return *(T*)addr;
00507 }
00508
00509
00510
00511 inline int
00512 Jdb::was_last_cmd()
00513 {
00514 return last_cmd;
00515 }
00516
00517
00518
00519 inline int
00520 Jdb::get_next_cmd()
00521 {
00522 return next_cmd;
00523 }
00524
00525
00526
00527 inline void
00528 Jdb::set_next_cmd(char c)
00529 {
00530 next_cmd = c;
00531 }
00532
00533
00534
00535 inline Address_type
00536 Jdb_entry_frame::from_user()
00537 {
00538 return cs & 3 ? ADDR_USER : ADDR_KERNEL;
00539 }
00540
00541
00542
00543 inline Address
00544 Jdb_entry_frame::get_ksp()
00545 {
00546 return (Address)&esp;
00547 }
00548
00549
00550
00551 inline Address
00552 Jdb_entry_frame::_get_esp()
00553 {
00554 return from_user() ? esp : get_ksp();
00555 }
00556
00557
00558
00559 inline Mword
00560 Jdb_entry_frame::param()
00561 {
00562 return eax;
00563 }
00564
00565
00566
00567 inline Mword
00568 Jdb_entry_frame::_get_ss()
00569 {
00570 return from_user() ? ss : Cpu::get_ss();
00571 }
00572
00573
00574
00575
00576
00577
00578
00579
00580 template <typename T> T
00581 Jdb::peek(T const *addr)
00582 {
00583 return current_space()->peek(addr, entry_frame->from_user());
00584 }
00585
00586 #endif // jdb_h