GDB (API)
|
00001 /* Startup code for Insight. 00002 00003 Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 200, 2002, 2003, 2004, 00004 2008, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. 00005 00006 Written by Stu Grossman <grossman@cygnus.com> of Cygnus Support. 00007 00008 This file is part of GDB. 00009 00010 This program is free software; you can redistribute it and/or modify 00011 it under the terms of the GNU General Public License as published by 00012 the Free Software Foundation; either version 2 of the License, or 00013 (at your option) any later version. 00014 00015 This program is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 GNU General Public License for more details. 00019 00020 You should have received a copy of the GNU General Public License 00021 along with this program; if not, write to the Free Software 00022 Foundation, Inc., 51 Franklin Street, Fifth Floor, 00023 Boston, MA 02110-1301, USA. */ 00024 00025 #include "defs.h" 00026 #include "inferior.h" 00027 #include "symfile.h" 00028 #include "objfiles.h" 00029 #include "gdbcore.h" 00030 #include "tracepoint.h" 00031 #include "demangle.h" 00032 #include "top.h" 00033 #include "annotate.h" 00034 #include "cli/cli-decode.h" 00035 #include "observer.h" 00036 #include "gdbthread.h" 00037 00038 #ifdef _WIN32 00039 #define WIN32_LEAN_AND_MEAN 00040 #include <windows.h> 00041 #endif 00042 00043 /* tcl header files includes varargs.h unless HAS_STDARG is defined, 00044 but gdb uses stdarg.h, so make sure HAS_STDARG is defined. */ 00045 #define HAS_STDARG 1 00046 00047 #include <tcl.h> 00048 #include <tk.h> 00049 #include "guitcl.h" 00050 #include "gdbtk.h" 00051 00052 #include <signal.h> 00053 #include <fcntl.h> 00054 #ifdef HAVE_SYS_IOCTL_H 00055 #include <sys/ioctl.h> 00056 #endif 00057 #include <sys/time.h> 00058 00059 #include "gdb_string.h" 00060 #include "dis-asm.h" 00061 #include "gdbcmd.h" 00062 00063 00064 volatile int in_fputs = 0; 00065 00066 /* Set by gdb_stop, this flag informs x_event to tell its caller 00067 that it should forcibly detach from the target. */ 00068 int gdbtk_force_detach = 0; 00069 00070 /* From gdbtk-bp.c */ 00071 extern void gdbtk_create_breakpoint (struct breakpoint *); 00072 extern void gdbtk_delete_breakpoint (struct breakpoint *); 00073 extern void gdbtk_modify_breakpoint (struct breakpoint *); 00074 00075 static void gdbtk_architecture_changed (struct gdbarch *); 00076 static void gdbtk_trace_find (char *arg, int from_tty); 00077 static void gdbtk_trace_start_stop (int, int); 00078 static void gdbtk_attach (void); 00079 static void gdbtk_detach (void); 00080 static void gdbtk_file_changed (char *); 00081 static void gdbtk_exec_file_display (char *); 00082 static void gdbtk_call_command (struct cmd_list_element *, char *, int); 00083 static ptid_t gdbtk_wait (ptid_t, struct target_waitstatus *, int); 00084 int x_event (int); 00085 static int gdbtk_query (const char *, va_list); 00086 static void gdbtk_warning (const char *, va_list); 00087 static char *gdbtk_readline (char *); 00088 static void gdbtk_readline_begin (char *format,...); 00089 static void gdbtk_readline_end (void); 00090 static void gdbtk_pre_add_symbol (const char *); 00091 static void gdbtk_print_frame_info (struct symtab *, int, int, int); 00092 static void gdbtk_post_add_symbol (void); 00093 static void gdbtk_register_changed (int regno); 00094 static void gdbtk_memory_changed (struct inferior *inferior, CORE_ADDR addr, 00095 ssize_t len, const bfd_byte *data); 00096 static void gdbtk_selected_frame_changed (int); 00097 static void gdbtk_context_change (int); 00098 static void gdbtk_error_begin (void); 00099 void report_error (void); 00100 static void gdbtk_annotate_signal (void); 00101 static void gdbtk_set_hook (struct cmd_list_element *cmdblk); 00102 00103 /* 00104 * gdbtk_fputs can't be static, because we need to call it in gdbtk.c. 00105 * See note there for details. 00106 */ 00107 00108 long gdbtk_read (struct ui_file *, char *, long); 00109 void gdbtk_fputs (const char *, struct ui_file *); 00110 static int gdbtk_load_hash (const char *, unsigned long); 00111 00112 static ptid_t gdbtk_ptid; 00113 00114 /* 00115 * gdbtk_add_hooks - add all the hooks to gdb. This will get called by the 00116 * startup code to fill in the hooks needed by core gdb. 00117 */ 00118 00119 void 00120 gdbtk_add_hooks (void) 00121 { 00122 /* Gdb observers */ 00123 observer_attach_breakpoint_created (gdbtk_create_breakpoint); 00124 observer_attach_breakpoint_modified (gdbtk_modify_breakpoint); 00125 observer_attach_breakpoint_deleted (gdbtk_delete_breakpoint); 00126 observer_attach_architecture_changed (gdbtk_architecture_changed); 00127 observer_attach_memory_changed (gdbtk_memory_changed); 00128 00129 /* Hooks */ 00130 deprecated_call_command_hook = gdbtk_call_command; 00131 deprecated_set_hook = gdbtk_set_hook; 00132 deprecated_readline_begin_hook = gdbtk_readline_begin; 00133 deprecated_readline_hook = gdbtk_readline; 00134 deprecated_readline_end_hook = gdbtk_readline_end; 00135 00136 deprecated_print_frame_info_listing_hook = gdbtk_print_frame_info; 00137 deprecated_query_hook = gdbtk_query; 00138 deprecated_warning_hook = gdbtk_warning; 00139 00140 deprecated_interactive_hook = gdbtk_interactive; 00141 deprecated_target_wait_hook = gdbtk_wait; 00142 deprecated_ui_load_progress_hook = gdbtk_load_hash; 00143 00144 deprecated_ui_loop_hook = x_event; 00145 deprecated_pre_add_symbol_hook = gdbtk_pre_add_symbol; 00146 deprecated_post_add_symbol_hook = gdbtk_post_add_symbol; 00147 deprecated_file_changed_hook = gdbtk_file_changed; 00148 specify_exec_file_hook (gdbtk_exec_file_display); 00149 00150 deprecated_trace_find_hook = gdbtk_trace_find; 00151 deprecated_trace_start_stop_hook = gdbtk_trace_start_stop; 00152 00153 deprecated_attach_hook = gdbtk_attach; 00154 deprecated_detach_hook = gdbtk_detach; 00155 00156 deprecated_register_changed_hook = gdbtk_register_changed; 00157 deprecated_selected_frame_level_changed_hook = gdbtk_selected_frame_changed; 00158 deprecated_context_hook = gdbtk_context_change; 00159 00160 deprecated_error_begin_hook = gdbtk_error_begin; 00161 00162 deprecated_annotate_signal_hook = gdbtk_annotate_signal; 00163 deprecated_annotate_signalled_hook = gdbtk_annotate_signal; 00164 } 00165 00166 /* These control where to put the gdb output which is created by 00167 {f}printf_{un}filtered and friends. gdbtk_fputs is the lowest 00168 level of these routines and capture all output from the rest of 00169 GDB. 00170 00171 The reason to use the result_ptr rather than the gdbtk_interp's result 00172 directly is so that a call_wrapper invoked function can preserve its result 00173 across calls into Tcl which might be made in the course of the function's 00174 execution. 00175 00176 * result_ptr->obj_ptr is where to accumulate the result. 00177 * GDBTK_TO_RESULT flag means the output goes to the gdbtk_tcl_fputs proc 00178 instead of to the result_ptr. 00179 * GDBTK_MAKES_LIST flag means add to the result as a list element. 00180 00181 */ 00182 00183 gdbtk_result *result_ptr = NULL; 00184 00185 /* If you want to restore an old value of result_ptr whenever cleanups 00186 are run, pass this function to make_cleanup, along with the value 00187 of result_ptr you'd like to reinstate. */ 00188 void 00189 gdbtk_restore_result_ptr (void *old_result_ptr) 00190 { 00191 result_ptr = (gdbtk_result *) old_result_ptr; 00192 } 00193 00194 /* This allows you to Tcl_Eval a tcl command which takes 00195 a command word, and then a single argument. */ 00196 int 00197 gdbtk_two_elem_cmd (char *cmd_name, char *argv1) 00198 { 00199 char *command; 00200 int result, flags_ptr, arg_len, cmd_len; 00201 00202 arg_len = Tcl_ScanElement (argv1, &flags_ptr); 00203 cmd_len = strlen (cmd_name); 00204 command = malloc (arg_len + cmd_len + 2); 00205 strcpy (command, cmd_name); 00206 strcat (command, " "); 00207 00208 Tcl_ConvertElement (argv1, command + cmd_len + 1, flags_ptr); 00209 00210 result = Tcl_Eval (gdbtk_interp, command); 00211 if (result != TCL_OK) 00212 report_error (); 00213 free (command); 00214 return result; 00215 } 00216 00217 struct ui_file * 00218 gdbtk_fileopenin (void) 00219 { 00220 struct ui_file *file = ui_file_new (); 00221 set_ui_file_read (file, gdbtk_read); 00222 return file; 00223 } 00224 00225 struct ui_file * 00226 gdbtk_fileopen (void) 00227 { 00228 struct ui_file *file = ui_file_new (); 00229 set_ui_file_fputs (file, gdbtk_fputs); 00230 return file; 00231 } 00232 00233 /* This handles input from the gdb console. 00234 */ 00235 00236 long 00237 gdbtk_read (struct ui_file *stream, char *buf, long sizeof_buf) 00238 { 00239 int result; 00240 size_t actual_len; 00241 00242 if (stream == gdb_stdtargin) 00243 { 00244 result = Tcl_Eval (gdbtk_interp, "gdbtk_console_read"); 00245 if (result != TCL_OK) 00246 { 00247 report_error (); 00248 actual_len = 0; 00249 buf[0] = '\0'; 00250 return 0; 00251 } 00252 else 00253 { 00254 const char *tclResult = Tcl_GetStringResult (gdbtk_interp); 00255 actual_len = strlen (tclResult); 00256 00257 /* Truncate the string if it is too big for the caller's buffer. */ 00258 if (actual_len >= sizeof_buf) 00259 actual_len = sizeof_buf - 1; 00260 00261 memcpy (buf, tclResult, actual_len); 00262 buf[actual_len] = '\0'; 00263 return actual_len; 00264 } 00265 } 00266 else 00267 { 00268 errno = EBADF; 00269 return 0; 00270 } 00271 } 00272 00273 00274 /* This handles all the output from gdb. All the gdb printf_xxx functions 00275 * eventually end up here. The output is either passed to the result_ptr 00276 * where it will go to the result of some gdbtk command, or passed to the 00277 * Tcl proc gdbtk_tcl_fputs (where it is usually just dumped to the console 00278 * window. 00279 * 00280 * The cases are: 00281 * 00282 * 1) result_ptr == NULL - This happens when some output comes from gdb which 00283 * is not generated by a command in gdbtk-cmds, usually startup stuff. 00284 * In this case we just route the data to gdbtk_tcl_fputs. 00285 * 2) The GDBTK_TO_RESULT flag is set - The result is supposed to go to Tcl. 00286 * We place the data into the result_ptr, either as a string, 00287 * or a list, depending whether the GDBTK_MAKES_LIST bit is set. 00288 * 3) The GDBTK_TO_RESULT flag is unset - We route the data to gdbtk_tcl_fputs 00289 * UNLESS it was coming to gdb_stderr. Then we place it in the result_ptr 00290 * anyway, so it can be dealt with. 00291 * 00292 */ 00293 00294 void 00295 gdbtk_fputs (const char *ptr, struct ui_file *stream) 00296 { 00297 if (gdbtk_disable_fputs) 00298 return; 00299 00300 in_fputs = 1; 00301 00302 if (stream == gdb_stdlog) 00303 gdbtk_two_elem_cmd ("gdbtk_tcl_fputs_log", (char *) ptr); 00304 else if (stream == gdb_stdtarg) 00305 gdbtk_two_elem_cmd ("gdbtk_tcl_fputs_target", (char *) ptr); 00306 else if (result_ptr != NULL) 00307 { 00308 if (result_ptr->flags & GDBTK_TO_RESULT) 00309 { 00310 if (result_ptr->flags & GDBTK_MAKES_LIST) 00311 Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, 00312 Tcl_NewStringObj ((char *) ptr, -1)); 00313 else 00314 Tcl_AppendToObj (result_ptr->obj_ptr, (char *) ptr, -1); 00315 } 00316 else if (stream == gdb_stderr || result_ptr->flags & GDBTK_ERROR_ONLY) 00317 { 00318 if (result_ptr->flags & GDBTK_ERROR_STARTED) 00319 Tcl_AppendToObj (result_ptr->obj_ptr, (char *) ptr, -1); 00320 else 00321 { 00322 Tcl_SetStringObj (result_ptr->obj_ptr, (char *) ptr, -1); 00323 result_ptr->flags |= GDBTK_ERROR_STARTED; 00324 } 00325 } 00326 else 00327 { 00328 gdbtk_two_elem_cmd ("gdbtk_tcl_fputs", (char *) ptr); 00329 if (result_ptr->flags & GDBTK_MAKES_LIST) 00330 gdbtk_two_elem_cmd ("gdbtk_tcl_fputs", " "); 00331 } 00332 } 00333 else 00334 { 00335 gdbtk_two_elem_cmd ("gdbtk_tcl_fputs", (char *) ptr); 00336 } 00337 00338 in_fputs = 0; 00339 } 00340 00341 /* 00342 * This routes all warnings to the Tcl function "gdbtk_tcl_warning". 00343 */ 00344 00345 static void 00346 gdbtk_warning (const char *warning, va_list args) 00347 { 00348 char *buf; 00349 buf = xstrvprintf (warning, args); 00350 gdbtk_two_elem_cmd ("gdbtk_tcl_warning", buf); 00351 free(buf); 00352 } 00353 00354 00355 /* Error-handling function for all hooks */ 00356 /* Hooks are not like tcl functions, they do not simply return */ 00357 /* TCL_OK or TCL_ERROR. Also, the calling function typically */ 00358 /* doesn't care about errors in the hook functions. Therefore */ 00359 /* after every hook function, report_error should be called. */ 00360 /* report_error can just call Tcl_BackgroundError() which will */ 00361 /* pop up a messagebox, or it can silently log the errors through */ 00362 /* the gdbtk dbug command. */ 00363 00364 void 00365 report_error (void) 00366 { 00367 TclDebug ('E', Tcl_GetVar (gdbtk_interp, "errorInfo", TCL_GLOBAL_ONLY)); 00368 /* Tcl_BackgroundError(gdbtk_interp); */ 00369 } 00370 00371 /* 00372 * This routes all ignorable warnings to the Tcl function 00373 * "gdbtk_tcl_ignorable_warning". 00374 */ 00375 00376 void 00377 gdbtk_ignorable_warning (const char *class, const char *warning) 00378 { 00379 char *buf; 00380 buf = xstrprintf ("gdbtk_tcl_ignorable_warning {%s} {%s}", class, warning); 00381 if (Tcl_Eval (gdbtk_interp, buf) != TCL_OK) 00382 report_error (); 00383 free(buf); 00384 } 00385 00386 static void 00387 gdbtk_register_changed (int regno) 00388 { 00389 if (Tcl_Eval (gdbtk_interp, "gdbtk_register_changed") != TCL_OK) 00390 report_error (); 00391 } 00392 00393 static void 00394 gdbtk_memory_changed (struct inferior *inferior, CORE_ADDR addr, 00395 ssize_t len, const bfd_byte *data) 00396 { 00397 if (Tcl_Eval (gdbtk_interp, "gdbtk_memory_changed") != TCL_OK) 00398 report_error (); 00399 } 00400 00401 00402 /* This hook is installed as the deprecated_ui_loop_hook, which is 00403 * used in several places to keep the gui alive (x_event runs gdbtk's 00404 * event loop). Users include: 00405 * - ser-tcp.c in socket reading code 00406 * - ser-unix.c in serial port reading code 00407 * - built-in simulators while executing 00408 * 00409 * x_event used to be called on SIGIO on the socket to the X server 00410 * for unix. Unfortunately, Linux does not deliver SIGIO, so we resort 00411 * to an elaborate scheme to keep the gui alive. 00412 * 00413 * For simulators and socket or serial connections on all hosts, we 00414 * rely on deprecated_ui_loop_hook (x_event) to keep us going. If the 00415 * user requests a detach (as a result of pressing the stop button -- 00416 * see comments before gdb_stop in gdbtk-cmds.c), it sets the global 00417 * GDBTK_FORCE_DETACH, which is the value that x_event returns to it's 00418 * caller. It is up to the caller of x_event to act on this 00419 * information. 00420 * 00421 * For native unix, we simply set an interval timer which calls 00422 * x_event to allow the debugger to run through the Tcl event 00423 * loop. See comments before gdbtk_start_timer and gdb_stop_timer 00424 * in gdbtk.c. 00425 * 00426 * For native windows (and a few other targets, like the v850 ICE), we 00427 * rely on the target_wait loops to call deprecated_ui_loop_hook to 00428 * keep us alive. */ 00429 int 00430 x_event (int signo) 00431 { 00432 static volatile int in_x_event = 0; 00433 static Tcl_Obj *varname = NULL; 00434 00435 /* Do nor re-enter this code or enter it while collecting gdb output. */ 00436 if (in_x_event || in_fputs) 00437 return 0; 00438 00439 /* Also, only do things while the target is running (stops and redraws). 00440 FIXME: We wold like to at least redraw at other times but this is bundled 00441 together in the TCL_WINDOW_EVENTS group and we would also process user 00442 input. We will have to prevent (unwanted) user input to be generated 00443 in order to be able to redraw (removing this test here). */ 00444 if (!running_now) 00445 return 0; 00446 00447 in_x_event = 1; 00448 gdbtk_force_detach = 0; 00449 00450 /* Process pending events */ 00451 while (Tcl_DoOneEvent (TCL_DONT_WAIT | TCL_ALL_EVENTS) != 0) 00452 ; 00453 00454 if (load_in_progress) 00455 { 00456 int val; 00457 if (varname == NULL) 00458 { 00459 #if TCL_MAJOR_VERSION == 8 && (TCL_MINOR_VERSION < 1 || TCL_MINOR_VERSION > 2) 00460 Tcl_Obj *varnamestrobj = Tcl_NewStringObj ("download_cancel_ok", -1); 00461 varname = Tcl_ObjGetVar2 (gdbtk_interp, varnamestrobj, NULL, TCL_GLOBAL_ONLY); 00462 #else 00463 varname = Tcl_GetObjVar2 (gdbtk_interp, "download_cancel_ok", NULL, TCL_GLOBAL_ONLY); 00464 #endif 00465 } 00466 if ((Tcl_GetIntFromObj (gdbtk_interp, varname, &val) == TCL_OK) && val) 00467 { 00468 set_quit_flag (); 00469 #ifdef REQUEST_QUIT 00470 REQUEST_QUIT; 00471 #else 00472 if (immediate_quit) 00473 quit (); 00474 #endif 00475 } 00476 } 00477 in_x_event = 0; 00478 00479 return gdbtk_force_detach; 00480 } 00481 00482 /* VARARGS */ 00483 static void 00484 gdbtk_readline_begin (char *format,...) 00485 { 00486 va_list args; 00487 char *buf; 00488 00489 va_start (args, format); 00490 buf = xstrvprintf (format, args); 00491 gdbtk_two_elem_cmd ("gdbtk_tcl_readline_begin", buf); 00492 free(buf); 00493 } 00494 00495 static char * 00496 gdbtk_readline (char *prompt) 00497 { 00498 int result; 00499 00500 #ifdef _WIN32 00501 close_bfds (); 00502 #endif 00503 00504 result = gdbtk_two_elem_cmd ("gdbtk_tcl_readline", prompt); 00505 00506 if (result == TCL_OK) 00507 { 00508 return (xstrdup (Tcl_GetStringResult (gdbtk_interp))); 00509 } 00510 else 00511 { 00512 gdbtk_fputs (Tcl_GetStringResult (gdbtk_interp), gdb_stdout); 00513 gdbtk_fputs ("\n", gdb_stdout); 00514 return (NULL); 00515 } 00516 } 00517 00518 static void 00519 gdbtk_readline_end (void) 00520 { 00521 if (Tcl_Eval (gdbtk_interp, "gdbtk_tcl_readline_end") != TCL_OK) 00522 report_error (); 00523 } 00524 00525 static void 00526 gdbtk_call_command (struct cmd_list_element *cmdblk, 00527 char *arg, int from_tty) 00528 { 00529 running_now = 0; 00530 if (cmdblk->class == class_run || cmdblk->class == class_trace) 00531 { 00532 00533 running_now = 1; 00534 if (!No_Update) 00535 Tcl_Eval (gdbtk_interp, "gdbtk_tcl_busy"); 00536 cmd_func (cmdblk, arg, from_tty); 00537 running_now = 0; 00538 if (!No_Update) 00539 Tcl_Eval (gdbtk_interp, "gdbtk_tcl_idle"); 00540 } 00541 else 00542 cmd_func (cmdblk, arg, from_tty); 00543 } 00544 00545 /* Called after a `set' command succeeds. Runs the Tcl hook 00546 `gdb_set_hook' with the full name of the variable (a Tcl list) as 00547 the first argument and the new value as the second argument. */ 00548 00549 static void 00550 gdbtk_set_hook (struct cmd_list_element *cmdblk) 00551 { 00552 Tcl_DString cmd; 00553 char *p; 00554 char *buffer = NULL; 00555 00556 Tcl_DStringInit (&cmd); 00557 Tcl_DStringAppendElement (&cmd, "gdbtk_tcl_set_variable"); 00558 00559 /* Append variable name as sublist. */ 00560 Tcl_DStringStartSublist (&cmd); 00561 p = cmdblk->prefixname; 00562 while (p && *p) 00563 { 00564 char *q = strchr (p, ' '); 00565 char save = '\0'; 00566 if (q) 00567 { 00568 save = *q; 00569 *q = '\0'; 00570 } 00571 Tcl_DStringAppendElement (&cmd, p); 00572 if (q) 00573 *q = save; 00574 p = q + 1; 00575 } 00576 Tcl_DStringAppendElement (&cmd, cmdblk->name); 00577 Tcl_DStringEndSublist (&cmd); 00578 00579 switch (cmdblk->var_type) 00580 { 00581 case var_string_noescape: 00582 case var_filename: 00583 case var_enum: 00584 case var_string: 00585 Tcl_DStringAppendElement (&cmd, (*(char **) cmdblk->var 00586 ? *(char **) cmdblk->var 00587 : "(null)")); 00588 break; 00589 00590 case var_boolean: 00591 Tcl_DStringAppendElement (&cmd, (*(int *) cmdblk->var ? "1" : "0")); 00592 break; 00593 00594 case var_uinteger: 00595 case var_zinteger: 00596 buffer = xstrprintf ("%u", *(unsigned int *) cmdblk->var); 00597 Tcl_DStringAppendElement (&cmd, buffer); 00598 break; 00599 00600 case var_integer: 00601 buffer = xstrprintf ("%d", *(int *) cmdblk->var); 00602 Tcl_DStringAppendElement (&cmd, buffer); 00603 break; 00604 00605 default: 00606 /* This case should already be trapped by the hook caller. */ 00607 Tcl_DStringAppendElement (&cmd, "error"); 00608 break; 00609 } 00610 00611 if (Tcl_Eval (gdbtk_interp, Tcl_DStringValue (&cmd)) != TCL_OK) 00612 report_error (); 00613 00614 Tcl_DStringFree (&cmd); 00615 00616 if (buffer != NULL) 00617 { 00618 free(buffer); 00619 } 00620 } 00621 00622 int 00623 gdbtk_load_hash (const char *section, unsigned long num) 00624 { 00625 char *buf; 00626 buf = xstrprintf ("Download::download_hash %s %ld", section, num); 00627 if (Tcl_Eval (gdbtk_interp, buf) != TCL_OK) 00628 report_error (); 00629 free(buf); 00630 00631 return atoi (Tcl_GetStringResult (gdbtk_interp)); 00632 } 00633 00634 00635 /* This hook is called whenever we are ready to load a symbol file so that 00636 the UI can notify the user... */ 00637 static void 00638 gdbtk_pre_add_symbol (const char *name) 00639 { 00640 gdbtk_two_elem_cmd ("gdbtk_tcl_pre_add_symbol", (char *) name); 00641 } 00642 00643 /* This hook is called whenever we finish loading a symbol file. */ 00644 static void 00645 gdbtk_post_add_symbol (void) 00646 { 00647 if (Tcl_Eval (gdbtk_interp, "gdbtk_tcl_post_add_symbol") != TCL_OK) 00648 report_error (); 00649 } 00650 00651 /* This hook function is called whenever we want to wait for the 00652 target. */ 00653 00654 static ptid_t 00655 gdbtk_wait (ptid_t ptid, struct target_waitstatus *ourstatus, int options) 00656 { 00657 gdbtk_force_detach = 0; 00658 gdbtk_start_timer (); 00659 ptid = target_wait (ptid, ourstatus, options); 00660 gdbtk_stop_timer (); 00661 gdbtk_ptid = ptid; 00662 00663 return ptid; 00664 } 00665 00666 /* 00667 * This handles all queries from gdb. 00668 * The first argument is a printf style format statement, the rest are its 00669 * arguments. The resultant formatted string is passed to the Tcl function 00670 * "gdbtk_tcl_query". 00671 * It returns the users response to the query, as well as putting the value 00672 * in the result field of the Tcl interpreter. 00673 */ 00674 00675 static int 00676 gdbtk_query (const char *query, va_list args) 00677 { 00678 char *buf; 00679 long val; 00680 00681 buf = xstrvprintf (query, args); 00682 gdbtk_two_elem_cmd ("gdbtk_tcl_query", buf); 00683 free(buf); 00684 00685 val = atol (Tcl_GetStringResult (gdbtk_interp)); 00686 return val; 00687 } 00688 00689 00690 static void 00691 gdbtk_print_frame_info (struct symtab *s, int line, 00692 int stopline, int noerror) 00693 { 00694 } 00695 00696 /* 00697 * gdbtk_trace_find 00698 * 00699 * This is run by the trace_find_command. arg is the argument that was passed 00700 * to that command, from_tty is 1 if the command was run from a tty, 0 if it 00701 * was run from a script. It runs gdbtk_tcl_tfind_hook passing on these two 00702 * arguments. 00703 * 00704 */ 00705 00706 static void 00707 gdbtk_trace_find (char *arg, int from_tty) 00708 { 00709 Tcl_Obj *cmdObj; 00710 00711 cmdObj = Tcl_NewListObj (0, NULL); 00712 Tcl_ListObjAppendElement (gdbtk_interp, cmdObj, 00713 Tcl_NewStringObj ("gdbtk_tcl_trace_find_hook", -1)); 00714 Tcl_ListObjAppendElement (gdbtk_interp, cmdObj, Tcl_NewStringObj (arg, -1)); 00715 Tcl_ListObjAppendElement (gdbtk_interp, cmdObj, Tcl_NewIntObj (from_tty)); 00716 #if TCL_MAJOR_VERSION == 8 && (TCL_MINOR_VERSION < 1 || TCL_MINOR_VERSION > 2) 00717 if (Tcl_GlobalEvalObj (gdbtk_interp, cmdObj) != TCL_OK) 00718 report_error (); 00719 #else 00720 if (Tcl_EvalObj (gdbtk_interp, cmdObj, TCL_EVAL_GLOBAL) != TCL_OK) 00721 report_error (); 00722 #endif 00723 } 00724 00725 /* 00726 * gdbtk_trace_start_stop 00727 * 00728 * This is run by the trace_start_command and trace_stop_command. 00729 * The START variable determines which, 1 meaning trace_start was run, 00730 * 0 meaning trace_stop was run. 00731 * 00732 */ 00733 00734 static void 00735 gdbtk_trace_start_stop (int start, int from_tty) 00736 { 00737 00738 if (start) 00739 Tcl_GlobalEval (gdbtk_interp, "gdbtk_tcl_tstart"); 00740 else 00741 Tcl_GlobalEval (gdbtk_interp, "gdbtk_tcl_tstop"); 00742 00743 } 00744 00745 static void 00746 gdbtk_selected_frame_changed (int level) 00747 { 00748 #if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION < 1 00749 char *a; 00750 a = xstrprintf ("%d", level); 00751 Tcl_SetVar (gdbtk_interp, "gdb_selected_frame_level", a, TCL_GLOBAL_ONLY); 00752 xfree (a); 00753 #else 00754 Tcl_SetVar2Ex (gdbtk_interp, "gdb_selected_frame_level", NULL, 00755 Tcl_NewIntObj (level), TCL_GLOBAL_ONLY); 00756 #endif 00757 } 00758 00759 /* Called when the current thread changes. */ 00760 /* gdb_context is linked to the tcl variable "gdb_context_id" */ 00761 static void 00762 gdbtk_context_change (int num) 00763 { 00764 gdb_context = num; 00765 } 00766 00767 /* Called from file_command */ 00768 static void 00769 gdbtk_file_changed (char *filename) 00770 { 00771 gdbtk_two_elem_cmd ("gdbtk_tcl_file_changed", filename); 00772 } 00773 00774 /* Called from exec_file_command */ 00775 static void 00776 gdbtk_exec_file_display (char *filename) 00777 { 00778 gdbtk_two_elem_cmd ("gdbtk_tcl_exec_file_display", filename); 00779 } 00780 00781 /* Called from error_begin, this hook is used to warn the gui 00782 about multi-line error messages */ 00783 static void 00784 gdbtk_error_begin (void) 00785 { 00786 if (result_ptr != NULL) 00787 result_ptr->flags |= GDBTK_ERROR_ONLY; 00788 } 00789 00790 /* notify GDBtk when a signal occurs */ 00791 static void 00792 gdbtk_annotate_signal (void) 00793 { 00794 char *buf; 00795 struct thread_info *tp; 00796 00797 /* Inform gui that the target has stopped. This is 00798 a necessary stop button evil. We don't want signal notification 00799 to interfere with the elaborate and painful stop button detach 00800 timeout. */ 00801 Tcl_Eval (gdbtk_interp, "gdbtk_stop_idle_callback"); 00802 00803 if (ptid_equal (inferior_ptid, null_ptid)) 00804 return; 00805 00806 tp = inferior_thread (); 00807 00808 buf = xstrprintf ("gdbtk_signal %s {%s}", 00809 gdb_signal_to_name (tp->suspend.stop_signal), 00810 gdb_signal_to_string (tp->suspend.stop_signal)); 00811 if (Tcl_Eval (gdbtk_interp, buf) != TCL_OK) 00812 report_error (); 00813 free(buf); 00814 } 00815 00816 static void 00817 gdbtk_attach (void) 00818 { 00819 if (Tcl_Eval (gdbtk_interp, "after idle \"update idletasks;gdbtk_attached\"") != TCL_OK) 00820 { 00821 report_error (); 00822 } 00823 } 00824 00825 static void 00826 gdbtk_detach (void) 00827 { 00828 if (Tcl_Eval (gdbtk_interp, "gdbtk_detached") != TCL_OK) 00829 { 00830 report_error (); 00831 } 00832 } 00833 00834 /* Called from gdbarch_update_p whenever the architecture changes. */ 00835 static void 00836 gdbtk_architecture_changed (struct gdbarch *ignore) 00837 { 00838 Tcl_Eval (gdbtk_interp, "gdbtk_tcl_architecture_changed"); 00839 } 00840 00841 ptid_t 00842 gdbtk_get_ptid (void) 00843 { 00844 return gdbtk_ptid; 00845 }