GDB (API)
/home/stan/gdb/src/gdb/gdbtk/generic/gdbtk-hooks.c
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines