1 /* Tcl/Tk interface routines.
2 Copyright 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
6 This file is part of GDB.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
31 #include "tracepoint.h"
47 /* start-sanitize-ide */
51 /* end-sanitize-ide */
54 #ifdef ANSI_PROTOTYPES
64 #include <sys/ioctl.h>
65 #include "gdb_string.h"
74 #define GDBTK_PATH_SEP ";"
76 #define GDBTK_PATH_SEP ":"
79 /* Some versions (1.3.79, 1.3.81) of Linux don't support SIOCSPGRP the way
80 gdbtk wants to use it... */
85 static int No_Update = 0;
86 static int load_in_progress = 0;
87 static int in_fputs = 0;
89 int gdbtk_load_hash PARAMS ((char *, unsigned long));
90 int (*ui_load_progress_hook) PARAMS ((char *, unsigned long));
91 void (*pre_add_symbol_hook) PARAMS ((char *));
92 void (*post_add_symbol_hook) PARAMS ((void));
94 char * get_prompt PARAMS ((void));
96 static void null_routine PARAMS ((int));
97 static void gdbtk_flush PARAMS ((FILE *));
98 static void gdbtk_fputs PARAMS ((const char *, FILE *));
99 static int gdbtk_query PARAMS ((const char *, va_list));
100 static void gdbtk_warning PARAMS ((const char *, va_list));
101 static void gdbtk_ignorable_warning PARAMS ((const char *, va_list));
102 static char *gdbtk_readline PARAMS ((char *));
103 static void gdbtk_init PARAMS ((char *));
104 static void tk_command_loop PARAMS ((void));
105 static void gdbtk_call_command PARAMS ((struct cmd_list_element *, char *, int));
106 static int gdbtk_wait PARAMS ((int, struct target_waitstatus *));
107 static void x_event PARAMS ((int));
108 static void gdbtk_interactive PARAMS ((void));
109 static void cleanup_init PARAMS ((int));
110 static void tk_command PARAMS ((char *, int));
111 static int gdb_disassemble PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
112 static int compare_lines PARAMS ((const PTR, const PTR));
113 static int gdbtk_dis_asm_read_memory PARAMS ((bfd_vma, bfd_byte *, int, disassemble_info *));
114 static int gdb_path_conv PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
115 static int gdb_stop PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
116 static int gdb_confirm_quit PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
117 static int gdb_force_quit PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
118 static int gdb_listfiles PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]));
119 static int gdb_listfuncs PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
120 static int call_wrapper PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
121 static int call_obj_wrapper PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST []));
122 static int gdb_cmd PARAMS ((ClientData, Tcl_Interp *, int, char *argv[]));
123 static int gdb_immediate_command PARAMS ((ClientData, Tcl_Interp *, int, char *argv[]));
124 static int gdb_fetch_registers PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
125 static void gdbtk_readline_end PARAMS ((void));
126 static void pc_changed PARAMS ((void));
127 static int gdb_changed_register_list PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
128 static void register_changed_p PARAMS ((int, void *));
129 static int gdb_get_breakpoint_list PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
130 static int gdb_get_breakpoint_info PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
131 static void breakpoint_notify PARAMS ((struct breakpoint *, const char *));
132 static void gdbtk_create_breakpoint PARAMS ((struct breakpoint *));
133 static void gdbtk_delete_breakpoint PARAMS ((struct breakpoint *));
134 static void gdbtk_modify_breakpoint PARAMS ((struct breakpoint *));
135 static int gdb_loc PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
136 static int gdb_eval PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
137 static int map_arg_registers PARAMS ((int, char *[], void (*) (int, void *), void *));
138 static void get_register_name PARAMS ((int, void *));
139 static int gdb_regnames PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
140 static void get_register PARAMS ((int, void *));
141 static int gdb_trace_status PARAMS ((ClientData, Tcl_Interp *, int, char *argv[]));
142 static int gdb_target_has_execution_command PARAMS ((ClientData, Tcl_Interp *, int, char *argv[]));
143 static int gdb_load_info PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]));
144 void TclDebug PARAMS ((const char *fmt, ...));
145 static int gdb_get_locals_command PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST
147 static int gdb_get_args_command PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST
149 static int gdb_get_vars_command PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]));
150 static int gdb_get_function_command PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]));
151 static int gdb_get_line_command PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]));
152 static int gdb_get_file_command PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]));
153 static int gdb_tracepoint_exists_command PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]));
154 static int gdb_get_tracepoint_info PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]));
155 static int gdb_actions_command PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]));
156 static int gdb_prompt_command PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]));
157 static int gdb_find_file_command PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]));
158 static int gdb_get_tracepoint_list PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]));
159 static void gdbtk_create_tracepoint PARAMS ((struct tracepoint *));
160 static void gdbtk_delete_tracepoint PARAMS ((struct tracepoint *));
161 static void gdbtk_modify_tracepoint PARAMS ((struct tracepoint *));
162 static void tracepoint_notify PARAMS ((struct tracepoint *, const char *));
163 static void gdbtk_print_frame_info PARAMS ((struct symtab *, int, int, int));
164 void gdbtk_pre_add_symbol PARAMS ((char *));
165 void gdbtk_post_add_symbol PARAMS ((void));
166 static int get_pc_register PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
167 static int gdb_loadfile PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]));
168 static int gdb_set_bp PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]));
169 static struct symtab *full_lookup_symtab PARAMS ((char *file));
170 static int gdb_get_mem PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
172 /* Handle for TCL interpreter */
173 static Tcl_Interp *interp = NULL;
175 static int gdbtk_timer_going = 0;
176 static void gdbtk_start_timer PARAMS ((void));
177 static void gdbtk_stop_timer PARAMS ((void));
179 /* This variable is true when the inferior is running. Although it's
180 possible to disable most input from widgets and thus prevent
181 attempts to do anything while the inferior is running, any commands
182 that get through - even a simple memory read - are Very Bad, and
183 may cause GDB to crash or behave strangely. So, this variable
184 provides an extra layer of defense. */
186 static int running_now;
188 /* This variable determines where memory used for disassembly is read from.
189 If > 0, then disassembly comes from the exec file rather than the
190 target (which might be at the other end of a slow serial link). If
191 == 0 then disassembly comes from target. If < 0 disassembly is
192 automatically switched to the target if it's an inferior process,
193 otherwise the exec file is used. */
195 static int disassemble_from_exec = -1;
199 /* Supply malloc calls for tcl/tk. We do not want to do this on
200 Windows, because Tcl_Alloc is probably in a DLL which will not call
201 the mmalloc routines. */
207 return xmalloc (size);
211 Tcl_Realloc (ptr, size)
215 return xrealloc (ptr, size);
225 #endif /* ! _WIN32 */
235 /* On Windows, if we hold a file open, other programs can't write to
236 it. In particular, we don't want to hold the executable open,
237 because it will mean that people have to get out of the debugging
238 session in order to remake their program. So we close it, although
239 this will cost us if and when we need to reopen it. */
249 bfd_cache_close (o->obfd);
252 if (exec_bfd != NULL)
253 bfd_cache_close (exec_bfd);
258 /* The following routines deal with stdout/stderr data, which is created by
259 {f}printf_{un}filtered and friends. gdbtk_fputs and gdbtk_flush are the
260 lowest level of these routines and capture all output from the rest of GDB.
261 Normally they present their data to tcl via callbacks to the following tcl
262 routines: gdbtk_tcl_fputs, gdbtk_tcl_fputs_error, and gdbtk_flush. These
263 in turn call tk routines to update the display.
265 Under some circumstances, you may want to collect the output so that it can
266 be returned as the value of a tcl procedure. This can be done by
267 surrounding the output routines with calls to start_saving_output and
268 finish_saving_output. The saved data can then be retrieved with
269 get_saved_output (but this must be done before the call to
270 finish_saving_output). */
272 /* Dynamic string for output. */
274 static Tcl_DString *result_ptr;
276 /* Dynamic string for stderr. This is only used if result_ptr is
279 static Tcl_DString *error_string_ptr;
286 /* Force immediate screen update */
288 Tcl_VarEval (interp, "gdbtk_tcl_flush", NULL);
293 gdbtk_fputs (ptr, stream)
297 char *merge[2], *command;
301 Tcl_DStringAppend (result_ptr, (char *) ptr, -1);
302 else if (error_string_ptr != NULL && stream == gdb_stderr)
303 Tcl_DStringAppend (error_string_ptr, (char *) ptr, -1);
306 merge[0] = "gdbtk_tcl_fputs";
307 merge[1] = (char *)ptr;
308 command = Tcl_Merge (2, merge);
309 Tcl_Eval (interp, command);
316 gdbtk_warning (warning, args)
320 char buf[200], *merge[2];
323 vsprintf (buf, warning, args);
324 merge[0] = "gdbtk_tcl_warning";
326 command = Tcl_Merge (2, merge);
327 Tcl_Eval (interp, command);
332 gdbtk_ignorable_warning (warning, args)
336 char buf[200], *merge[2];
339 vsprintf (buf, warning, args);
340 merge[0] = "gdbtk_tcl_ignorable_warning";
342 command = Tcl_Merge (2, merge);
343 Tcl_Eval (interp, command);
348 gdbtk_query (query, args)
352 char buf[200], *merge[2];
356 vsprintf (buf, query, args);
357 merge[0] = "gdbtk_tcl_query";
359 command = Tcl_Merge (2, merge);
360 Tcl_Eval (interp, command);
363 val = atol (interp->result);
369 #ifdef ANSI_PROTOTYPES
370 gdbtk_readline_begin (char *format, ...)
372 gdbtk_readline_begin (va_alist)
377 char buf[200], *merge[2];
380 #ifdef ANSI_PROTOTYPES
381 va_start (args, format);
385 format = va_arg (args, char *);
388 vsprintf (buf, format, args);
389 merge[0] = "gdbtk_tcl_readline_begin";
391 command = Tcl_Merge (2, merge);
392 Tcl_Eval (interp, command);
397 gdbtk_readline (prompt)
408 merge[0] = "gdbtk_tcl_readline";
410 command = Tcl_Merge (2, merge);
411 result = Tcl_Eval (interp, command);
413 if (result == TCL_OK)
415 return (strdup (interp -> result));
419 gdbtk_fputs (interp -> result, gdb_stdout);
420 gdbtk_fputs ("\n", gdb_stdout);
426 gdbtk_readline_end ()
428 Tcl_Eval (interp, "gdbtk_tcl_readline_end");
434 Tcl_Eval (interp, "gdbtk_pc_changed");
439 #ifdef ANSI_PROTOTYPES
440 dsprintf_append_element (Tcl_DString *dsp, char *format, ...)
442 dsprintf_append_element (va_alist)
449 #ifdef ANSI_PROTOTYPES
450 va_start (args, format);
456 dsp = va_arg (args, Tcl_DString *);
457 format = va_arg (args, char *);
460 vsprintf (buf, format, args);
462 Tcl_DStringAppendElement (dsp, buf);
466 gdb_path_conv (clientData, interp, argc, argv)
467 ClientData clientData;
473 char pathname[256], *ptr;
475 error ("wrong # args");
476 cygwin32_conv_to_full_win32_path (argv[1], pathname);
477 for (ptr = pathname; *ptr; ptr++)
483 char *pathname = argv[1];
485 Tcl_DStringAppend (result_ptr, pathname, strlen(pathname));
490 gdb_get_breakpoint_list (clientData, interp, argc, argv)
491 ClientData clientData;
496 struct breakpoint *b;
497 extern struct breakpoint *breakpoint_chain;
500 error ("wrong # args");
502 for (b = breakpoint_chain; b; b = b->next)
503 if (b->type == bp_breakpoint)
504 dsprintf_append_element (result_ptr, "%d", b->number);
510 gdb_get_breakpoint_info (clientData, interp, argc, argv)
511 ClientData clientData;
516 struct symtab_and_line sal;
517 static char *bptypes[] = {"breakpoint", "hardware breakpoint", "until",
518 "finish", "watchpoint", "hardware watchpoint",
519 "read watchpoint", "access watchpoint",
520 "longjmp", "longjmp resume", "step resume",
521 "through sigtramp", "watchpoint scope",
523 static char *bpdisp[] = {"delete", "delstop", "disable", "donttouch"};
524 struct command_line *cmd;
526 struct breakpoint *b;
527 extern struct breakpoint *breakpoint_chain;
528 char *funcname, *fname, *filename;
531 error ("wrong # args");
533 bpnum = atoi (argv[1]);
535 for (b = breakpoint_chain; b; b = b->next)
536 if (b->number == bpnum)
539 if (!b || b->type != bp_breakpoint)
540 error ("Breakpoint #%d does not exist", bpnum);
542 sal = find_pc_line (b->address, 0);
544 filename = symtab_to_filename (sal.symtab);
545 if (filename == NULL)
547 Tcl_DStringAppendElement (result_ptr, filename);
549 find_pc_partial_function (b->address, &funcname, NULL, NULL);
550 fname = cplus_demangle (funcname, 0);
553 Tcl_DStringAppendElement (result_ptr, fname);
557 Tcl_DStringAppendElement (result_ptr, funcname);
558 dsprintf_append_element (result_ptr, "%d", b->line_number);
559 dsprintf_append_element (result_ptr, "0x%lx", b->address);
560 Tcl_DStringAppendElement (result_ptr, bptypes[b->type]);
561 Tcl_DStringAppendElement (result_ptr, b->enable == enabled ? "1" : "0");
562 Tcl_DStringAppendElement (result_ptr, bpdisp[b->disposition]);
563 dsprintf_append_element (result_ptr, "%d", b->ignore_count);
565 Tcl_DStringStartSublist (result_ptr);
566 for (cmd = b->commands; cmd; cmd = cmd->next)
567 Tcl_DStringAppendElement (result_ptr, cmd->line);
568 Tcl_DStringEndSublist (result_ptr);
570 Tcl_DStringAppendElement (result_ptr, b->cond_string);
572 dsprintf_append_element (result_ptr, "%d", b->thread);
573 dsprintf_append_element (result_ptr, "%d", b->hit_count);
579 breakpoint_notify(b, action)
580 struct breakpoint *b;
585 struct symtab_and_line sal;
588 if (b->type != bp_breakpoint)
591 /* We ensure that ACTION contains no special Tcl characters, so we
593 sal = find_pc_line (b->address, 0);
594 filename = symtab_to_filename (sal.symtab);
595 if (filename == NULL)
598 sprintf (buf, "gdbtk_tcl_breakpoint %s %d 0x%lx %d {%s}", action, b->number,
599 (long)b->address, b->line_number, filename);
601 v = Tcl_Eval (interp, buf);
605 gdbtk_fputs (interp->result, gdb_stdout);
606 gdbtk_fputs ("\n", gdb_stdout);
611 gdbtk_create_breakpoint(b)
612 struct breakpoint *b;
614 breakpoint_notify (b, "create");
618 gdbtk_delete_breakpoint(b)
619 struct breakpoint *b;
621 breakpoint_notify (b, "delete");
625 gdbtk_modify_breakpoint(b)
626 struct breakpoint *b;
628 breakpoint_notify (b, "modify");
631 /* This implements the TCL command `gdb_loc', which returns a list */
632 /* consisting of the following: */
633 /* basename, function name, filename, line number, address, current pc */
636 gdb_loc (clientData, interp, argc, argv)
637 ClientData clientData;
643 struct symtab_and_line sal;
644 char *funcname, *fname;
647 if (!have_full_symbols () && !have_partial_symbols ())
649 Tcl_SetResult (interp, "No symbol table is loaded", TCL_STATIC);
655 if (selected_frame && (selected_frame->pc != stop_pc))
657 /* Note - this next line is not correct on all architectures. */
658 /* For a graphical debugged we really want to highlight the */
659 /* assembly line that called the next function on the stack. */
660 /* Many architectures have the next instruction saved as the */
661 /* pc on the stack, so what happens is the next instruction is hughlighted. */
663 pc = selected_frame->pc;
664 sal = find_pc_line (selected_frame->pc,
665 selected_frame->next != NULL
666 && !selected_frame->next->signal_handler_caller
667 && !frame_in_dummy (selected_frame->next));
672 sal = find_pc_line (stop_pc, 0);
677 struct symtabs_and_lines sals;
680 sals = decode_line_spec (argv[1], 1);
687 error ("Ambiguous line spec");
692 error ("wrong # args");
695 Tcl_DStringAppendElement (result_ptr, sal.symtab->filename);
697 Tcl_DStringAppendElement (result_ptr, "");
699 find_pc_partial_function (pc, &funcname, NULL, NULL);
700 fname = cplus_demangle (funcname, 0);
703 Tcl_DStringAppendElement (result_ptr, fname);
707 Tcl_DStringAppendElement (result_ptr, funcname);
708 filename = symtab_to_filename (sal.symtab);
709 if (filename == NULL)
712 Tcl_DStringAppendElement (result_ptr, filename);
713 dsprintf_append_element (result_ptr, "%d", sal.line); /* line number */
714 dsprintf_append_element (result_ptr, "0x%s", paddr_nz(pc)); /* PC in current frame */
715 dsprintf_append_element (result_ptr, "0x%s", paddr_nz(stop_pc)); /* Real PC */
719 /* This implements the TCL command `gdb_eval'. */
722 gdb_eval (clientData, interp, argc, argv)
723 ClientData clientData;
728 struct expression *expr;
729 struct cleanup *old_chain;
733 error ("wrong # args");
735 expr = parse_expression (argv[1]);
737 old_chain = make_cleanup (free_current_contents, &expr);
739 val = evaluate_expression (expr);
741 val_print (VALUE_TYPE (val), VALUE_CONTENTS (val), VALUE_ADDRESS (val),
742 gdb_stdout, 0, 0, 0, 0);
744 do_cleanups (old_chain);
749 /* gdb_get_mem addr form size num aschar*/
750 /* dump a block of memory */
751 /* addr: address of data to dump */
752 /* form: a char indicating format */
753 /* size: size of each element; 1,2,4, or 8 bytes*/
754 /* num: the number of bytes to read */
755 /* acshar: an optional ascii character to use in ASCII dump */
756 /* returns a list of elements followed by an optional */
760 gdb_get_mem (clientData, interp, argc, argv)
761 ClientData clientData;
766 int size, asize, i, j, bc;
768 int nbytes, rnum, bpr;
769 char format, c, *ptr, buff[128], aschar, *mbuf, *mptr, *cptr, *bptr;
770 struct type *val_type;
772 if (argc < 6 || argc > 7)
774 interp->result = "addr format size bytes bytes_per_row ?ascii_char?";
778 size = (int)strtoul(argv[3],(char **)NULL,0);
779 nbytes = (int)strtoul(argv[4],(char **)NULL,0);
780 bpr = (int)strtoul(argv[5],(char **)NULL,0);
781 if (nbytes <= 0 || bpr <= 0 || size <= 0)
783 interp->result = "Invalid number of bytes.";
787 addr = (CORE_ADDR)strtoul(argv[1],(char **)NULL,0);
789 mbuf = (char *)malloc (nbytes+32);
792 interp->result = "Out of memory.";
795 memset (mbuf, 0, nbytes+32);
798 rnum = target_read_memory_partial (addr, mbuf, nbytes, NULL);
807 val_type = builtin_type_char;
811 val_type = builtin_type_short;
815 val_type = builtin_type_int;
819 val_type = builtin_type_long_long;
823 val_type = builtin_type_char;
827 bc = 0; /* count of bytes in a row */
828 buff[0] = '"'; /* buffer for ascii dump */
829 bptr = &buff[1]; /* pointer for ascii dump */
831 for (i=0; i < nbytes; i+= size)
835 fputs_unfiltered ("N/A ", gdb_stdout);
837 for ( j = 0; j < size; j++)
842 print_scalar_formatted (mptr, val_type, format, asize, gdb_stdout);
843 fputs_unfiltered (" ", gdb_stdout);
846 for ( j = 0; j < size; j++)
849 if (c < 32 || c > 126)
861 if (aschar && (bc >= bpr))
863 /* end of row. print it and reset variables */
868 fputs_unfiltered (buff, gdb_stdout);
878 map_arg_registers (argc, argv, func, argp)
881 void (*func) PARAMS ((int regnum, void *argp));
886 /* Note that the test for a valid register must include checking the
887 reg_names array because NUM_REGS may be allocated for the union of the
888 register sets within a family of related processors. In this case, the
889 trailing entries of reg_names will change depending upon the particular
890 processor being debugged. */
892 if (argc == 0) /* No args, just do all the regs */
896 && reg_names[regnum] != NULL
897 && *reg_names[regnum] != '\000';
904 /* Else, list of register #s, just do listed regs */
905 for (; argc > 0; argc--, argv++)
907 regnum = atoi (*argv);
911 && reg_names[regnum] != NULL
912 && *reg_names[regnum] != '\000')
915 error ("bad register number");
922 get_register_name (regnum, argp)
924 void *argp; /* Ignored */
926 Tcl_DStringAppendElement (result_ptr, reg_names[regnum]);
929 /* This implements the TCL command `gdb_regnames', which returns a list of
930 all of the register names. */
933 gdb_regnames (clientData, interp, argc, argv)
934 ClientData clientData;
942 return map_arg_registers (argc, argv, get_register_name, NULL);
945 #ifndef REGISTER_CONVERTIBLE
946 #define REGISTER_CONVERTIBLE(x) (0 != 0)
949 #ifndef REGISTER_CONVERT_TO_VIRTUAL
950 #define REGISTER_CONVERT_TO_VIRTUAL(x, y, z, a)
953 #ifndef INVALID_FLOAT
954 #define INVALID_FLOAT(x, y) (0 != 0)
958 get_register (regnum, fp)
962 char raw_buffer[MAX_REGISTER_RAW_SIZE];
963 char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
964 int format = (int)fp;
969 if (read_relative_register_raw_bytes (regnum, raw_buffer))
971 Tcl_DStringAppendElement (result_ptr, "Optimized out");
975 /* Convert raw data to virtual format if necessary. */
977 if (REGISTER_CONVERTIBLE (regnum))
979 REGISTER_CONVERT_TO_VIRTUAL (regnum, REGISTER_VIRTUAL_TYPE (regnum),
980 raw_buffer, virtual_buffer);
983 memcpy (virtual_buffer, raw_buffer, REGISTER_VIRTUAL_SIZE (regnum));
988 printf_filtered ("0x");
989 for (j = 0; j < REGISTER_RAW_SIZE (regnum); j++)
991 register int idx = TARGET_BYTE_ORDER == BIG_ENDIAN ? j
992 : REGISTER_RAW_SIZE (regnum) - 1 - j;
993 printf_filtered ("%02x", (unsigned char)raw_buffer[idx]);
997 val_print (REGISTER_VIRTUAL_TYPE (regnum), virtual_buffer, 0,
998 gdb_stdout, format, 1, 0, Val_pretty_default);
1000 Tcl_DStringAppend (result_ptr, " ", -1);
1004 get_pc_register (clientData, interp, argc, argv)
1005 ClientData clientData;
1010 sprintf(interp->result,"0x%llx",(long long)read_register(PC_REGNUM));
1015 gdb_fetch_registers (clientData, interp, argc, argv)
1016 ClientData clientData;
1024 error ("wrong # args");
1030 return map_arg_registers (argc, argv, get_register, (void *) format);
1033 /* This contains the previous values of the registers, since the last call to
1034 gdb_changed_register_list. */
1036 static char old_regs[REGISTER_BYTES];
1039 register_changed_p (regnum, argp)
1041 void *argp; /* Ignored */
1043 char raw_buffer[MAX_REGISTER_RAW_SIZE];
1045 if (read_relative_register_raw_bytes (regnum, raw_buffer))
1048 if (memcmp (&old_regs[REGISTER_BYTE (regnum)], raw_buffer,
1049 REGISTER_RAW_SIZE (regnum)) == 0)
1052 /* Found a changed register. Save new value and return its number. */
1054 memcpy (&old_regs[REGISTER_BYTE (regnum)], raw_buffer,
1055 REGISTER_RAW_SIZE (regnum));
1057 dsprintf_append_element (result_ptr, "%d", regnum);
1061 gdb_changed_register_list (clientData, interp, argc, argv)
1062 ClientData clientData;
1070 return map_arg_registers (argc, argv, register_changed_p, NULL);
1073 /* This implements the tcl command "gdb_immediate", which does exactly
1074 the same thing as gdb_cmd, except NONE of its outut is buffered. */
1075 /* This will also ALWAYS cause the busy,update, and idle hooks to be
1076 called, contrasted with gdb_cmd, which NEVER calls them. */
1078 gdb_immediate_command (clientData, interp, argc, argv)
1079 ClientData clientData;
1084 Tcl_DString *save_ptr = NULL;
1087 error ("wrong # args");
1089 if (running_now || load_in_progress)
1094 Tcl_DStringAppend (result_ptr, "", -1);
1095 save_ptr = result_ptr;
1098 execute_command (argv[1], 1);
1100 bpstat_do_actions (&stop_bpstat);
1102 result_ptr = save_ptr;
1107 /* This implements the TCL command `gdb_cmd', which sends its argument into
1108 the GDB command scanner. */
1109 /* This command will never cause the update, idle and busy hooks to be called
1112 gdb_cmd (clientData, interp, argc, argv)
1113 ClientData clientData;
1118 Tcl_DString *save_ptr = NULL;
1121 error ("wrong # args");
1123 if (running_now || load_in_progress)
1128 /* for the load instruction (and possibly others later) we
1129 set result_ptr to NULL so gdbtk_fputs() will not buffer
1130 all the data until the command is finished. */
1132 if (strncmp ("load ", argv[1], 5) == 0
1133 || strncmp ("while ", argv[1], 6) == 0)
1135 Tcl_DStringAppend (result_ptr, "", -1);
1136 save_ptr = result_ptr;
1138 load_in_progress = 1;
1139 gdbtk_start_timer ();
1142 execute_command (argv[1], 1);
1144 if (load_in_progress)
1146 gdbtk_stop_timer ();
1147 load_in_progress = 0;
1150 bpstat_do_actions (&stop_bpstat);
1153 result_ptr = save_ptr;
1158 /* Client of call_wrapper - this routine performs the actual call to
1159 the client function. */
1161 struct wrapped_call_args
1172 struct wrapped_call_args *args;
1174 args->val = (*args->func) (args->func, args->interp, args->argc, args->argv);
1178 struct wrapped_call_objs
1188 wrapped_obj_call (args)
1189 struct wrapped_call_objs *args;
1191 args->val = (*args->func) (args->func, args->interp, args->objc, args->objv);
1195 /* This routine acts as a top-level for all GDB code called by tcl/Tk. It
1196 handles cleanups, and calls to return_to_top_level (usually via error).
1197 This is necessary in order to prevent a longjmp out of the bowels of Tk,
1198 possibly leaving things in a bad state. Since this routine can be called
1199 recursively, it needs to save and restore the contents of the jmp_buf as
1203 call_wrapper (clientData, interp, argc, argv)
1204 ClientData clientData;
1209 struct wrapped_call_args wrapped_args;
1210 Tcl_DString result, *old_result_ptr;
1211 Tcl_DString error_string, *old_error_string_ptr;
1213 Tcl_DStringInit (&result);
1214 old_result_ptr = result_ptr;
1215 result_ptr = &result;
1217 Tcl_DStringInit (&error_string);
1218 old_error_string_ptr = error_string_ptr;
1219 error_string_ptr = &error_string;
1221 wrapped_args.func = (Tcl_CmdProc *)clientData;
1222 wrapped_args.interp = interp;
1223 wrapped_args.argc = argc;
1224 wrapped_args.argv = argv;
1225 wrapped_args.val = 0;
1227 if (!catch_errors (wrapped_call, &wrapped_args, "", RETURN_MASK_ALL))
1229 wrapped_args.val = TCL_ERROR; /* Flag an error for TCL */
1231 /* Make sure the timer interrupts are turned off. */
1232 if (gdbtk_timer_going)
1233 gdbtk_stop_timer ();
1235 gdb_flush (gdb_stderr); /* Flush error output */
1236 gdb_flush (gdb_stdout); /* Sometimes error output comes here as well */
1238 /* In case of an error, we may need to force the GUI into idle
1239 mode because gdbtk_call_command may have bombed out while in
1240 the command routine. */
1243 Tcl_Eval (interp, "gdbtk_tcl_idle");
1246 /* do not suppress any errors -- a remote target could have errored */
1247 load_in_progress = 0;
1249 if (Tcl_DStringLength (&error_string) == 0)
1251 Tcl_DStringResult (interp, &result);
1252 Tcl_DStringFree (&error_string);
1254 else if (Tcl_DStringLength (&result) == 0)
1256 Tcl_DStringResult (interp, &error_string);
1257 Tcl_DStringFree (&result);
1258 Tcl_DStringFree (&error_string);
1262 Tcl_ResetResult (interp);
1263 Tcl_AppendResult (interp, Tcl_DStringValue (&result),
1264 Tcl_DStringValue (&error_string), (char *) NULL);
1265 Tcl_DStringFree (&result);
1266 Tcl_DStringFree (&error_string);
1269 result_ptr = old_result_ptr;
1270 error_string_ptr = old_error_string_ptr;
1276 return wrapped_args.val;
1279 call_obj_wrapper (clientData, interp, objc, objv)
1280 ClientData clientData;
1283 Tcl_Obj *CONST objv[];
1285 struct wrapped_call_objs wrapped_args;
1286 Tcl_DString result, *old_result_ptr;
1287 Tcl_DString error_string, *old_error_string_ptr;
1289 /* The obj call wrapper works differently from the string wrapper, because
1290 * the obj calls currently insert their results directly into the
1291 * interpreter's result. So there is no need to have a result_ptr...
1292 * FIXME - rewrite all the object commands so they use a result_obj_ptr
1293 * - rewrite all the string commands to be object commands.
1296 Tcl_DStringInit (&result);
1297 old_result_ptr = result_ptr;
1298 result_ptr = &result;
1300 Tcl_DStringInit (&error_string);
1302 Tcl_DStringInit (&error_string);
1303 old_error_string_ptr = error_string_ptr;
1304 error_string_ptr = &error_string;
1306 wrapped_args.func = (Tcl_CmdProc *)clientData;
1307 wrapped_args.interp = interp;
1308 wrapped_args.objc = objc;
1309 wrapped_args.objv = objv;
1310 wrapped_args.val = 0;
1312 if (!catch_errors (wrapped_obj_call, &wrapped_args, "", RETURN_MASK_ALL))
1314 wrapped_args.val = TCL_ERROR; /* Flag an error for TCL */
1316 /* Make sure the timer interrupts are turned off. */
1317 if (gdbtk_timer_going)
1318 gdbtk_stop_timer ();
1320 gdb_flush (gdb_stderr); /* Flush error output */
1321 gdb_flush (gdb_stdout); /* Sometimes error output comes here as well */
1323 /* In case of an error, we may need to force the GUI into idle
1324 mode because gdbtk_call_command may have bombed out while in
1325 the command routine. */
1328 Tcl_Eval (interp, "gdbtk_tcl_idle");
1331 /* do not suppress any errors -- a remote target could have errored */
1332 load_in_progress = 0;
1334 if (Tcl_DStringLength (&error_string) == 0)
1336 /* We should insert the result here, but the obj commands now
1337 * do this directly, so we don't need to.
1338 * FIXME - ultimately, all this should be redone so that all the
1339 * commands either manipulate the Tcl result directly, or use a result_ptr.
1342 Tcl_DStringFree (&error_string);
1344 else if (*(Tcl_GetStringResult (interp)) == '\0')
1346 Tcl_DStringResult (interp, &error_string);
1347 Tcl_DStringFree (&error_string);
1351 Tcl_AppendToObj(Tcl_GetObjResult(interp), Tcl_DStringValue (&error_string),
1352 Tcl_DStringLength (&error_string));
1353 Tcl_DStringFree (&error_string);
1356 result_ptr = old_result_ptr;
1357 error_string_ptr = old_error_string_ptr;
1363 return wrapped_args.val;
1367 comp_files (file1, file2)
1368 const char *file1[], *file2[];
1370 return strcmp(*file1,*file2);
1374 gdb_listfiles (clientData, interp, objc, objv)
1375 ClientData clientData;
1378 Tcl_Obj *CONST objv[];
1380 struct objfile *objfile;
1381 struct partial_symtab *psymtab;
1382 struct symtab *symtab;
1383 char *lastfile, *pathname, **files;
1385 int i, numfiles = 0, len = 0;
1389 files = (char **) xmalloc (sizeof (char *) * files_size);
1393 Tcl_WrongNumArgs (interp, 1, objv, "Usage: gdb_listfiles ?pathname?");
1397 pathname = Tcl_GetStringFromObj (objv[1], &len);
1399 mylist = Tcl_NewListObj (0, NULL);
1401 ALL_PSYMTABS (objfile, psymtab)
1403 if (numfiles == files_size)
1405 files_size = files_size * 2;
1406 files = (char **) xrealloc (files, sizeof (char *) * files_size);
1410 if (psymtab->filename)
1411 files[numfiles++] = basename(psymtab->filename);
1413 else if (!strcmp(psymtab->filename,basename(psymtab->filename))
1414 || !strncmp(pathname,psymtab->filename,len))
1415 if (psymtab->filename)
1416 files[numfiles++] = basename(psymtab->filename);
1419 ALL_SYMTABS (objfile, symtab)
1421 if (numfiles == files_size)
1423 files_size = files_size * 2;
1424 files = (char **) xrealloc (files, sizeof (char *) * files_size);
1428 if (symtab->filename)
1429 files[numfiles++] = basename(symtab->filename);
1431 else if (!strcmp(symtab->filename,basename(symtab->filename))
1432 || !strncmp(pathname,symtab->filename,len))
1433 if (symtab->filename)
1434 files[numfiles++] = basename(symtab->filename);
1437 qsort (files, numfiles, sizeof(char *), comp_files);
1440 for (i = 0; i < numfiles; i++)
1442 if (strcmp(files[i],lastfile))
1443 Tcl_ListObjAppendElement (interp, mylist, Tcl_NewStringObj(files[i], -1));
1444 lastfile = files[i];
1446 Tcl_SetObjResult (interp, mylist);
1452 gdb_listfuncs (clientData, interp, argc, argv)
1453 ClientData clientData;
1458 struct symtab *symtab;
1459 struct blockvector *bv;
1466 error ("wrong # args");
1468 symtab = full_lookup_symtab (argv[1]);
1470 error ("No such file");
1472 bv = BLOCKVECTOR (symtab);
1473 for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
1475 b = BLOCKVECTOR_BLOCK (bv, i);
1476 /* Skip the sort if this block is always sorted. */
1477 if (!BLOCK_SHOULD_SORT (b))
1478 sort_block_syms (b);
1479 for (j = 0; j < BLOCK_NSYMS (b); j++)
1481 sym = BLOCK_SYM (b, j);
1482 if (SYMBOL_CLASS (sym) == LOC_BLOCK)
1485 char *name = cplus_demangle (SYMBOL_NAME(sym), 0);
1488 sprintf (buf,"{%s} 1", name);
1491 sprintf (buf,"{%s} 0", SYMBOL_NAME(sym));
1492 Tcl_DStringAppendElement (result_ptr, buf);
1500 target_stop_wrapper (args)
1508 gdb_stop (clientData, interp, argc, argv)
1509 ClientData clientData;
1516 catch_errors (target_stop_wrapper, NULL, "",
1520 quit_flag = 1; /* hope something sees this */
1525 /* Prepare to accept a new executable file. This is called when we
1526 want to clear away everything we know about the old file, without
1527 asking the user. The Tcl code will have already asked the user if
1528 necessary. After this is called, we should be able to run the
1529 `file' command without getting any questions. */
1532 gdb_clear_file (clientData, interp, argc, argv)
1533 ClientData clientData;
1538 if (inferior_pid != 0 && target_has_execution)
1541 target_detach (NULL, 0);
1546 if (target_has_execution)
1549 symbol_file_command (NULL, 0);
1551 /* gdb_loc refers to stop_pc, but nothing seems to clear it, so we
1552 clear it here. FIXME: This seems like an abstraction violation
1559 /* Ask the user to confirm an exit request. */
1562 gdb_confirm_quit (clientData, interp, argc, argv)
1563 ClientData clientData;
1570 ret = quit_confirm ();
1571 Tcl_DStringAppendElement (result_ptr, ret ? "1" : "0");
1575 /* Quit without asking for confirmation. */
1578 gdb_force_quit (clientData, interp, argc, argv)
1579 ClientData clientData;
1584 quit_force ((char *) NULL, 1);
1588 /* This implements the TCL command `gdb_disassemble'. */
1591 gdbtk_dis_asm_read_memory (memaddr, myaddr, len, info)
1595 disassemble_info *info;
1597 extern struct target_ops exec_ops;
1601 res = xfer_memory (memaddr, myaddr, len, 0, &exec_ops);
1612 /* We need a different sort of line table from the normal one cuz we can't
1613 depend upon implicit line-end pc's for lines. This is because of the
1614 reordering we are about to do. */
1616 struct my_line_entry {
1623 compare_lines (mle1p, mle2p)
1627 struct my_line_entry *mle1, *mle2;
1630 mle1 = (struct my_line_entry *) mle1p;
1631 mle2 = (struct my_line_entry *) mle2p;
1633 val = mle1->line - mle2->line;
1638 return mle1->start_pc - mle2->start_pc;
1642 gdb_disassemble (clientData, interp, argc, argv)
1643 ClientData clientData;
1648 CORE_ADDR pc, low, high;
1649 int mixed_source_and_assembly;
1650 static disassemble_info di;
1651 static int di_initialized;
1653 if (! di_initialized)
1655 INIT_DISASSEMBLE_INFO_NO_ARCH (di, gdb_stdout,
1656 (fprintf_ftype) fprintf_unfiltered);
1657 di.flavour = bfd_target_unknown_flavour;
1658 di.memory_error_func = dis_asm_memory_error;
1659 di.print_address_func = dis_asm_print_address;
1663 di.mach = tm_print_insn_info.mach;
1664 if (TARGET_BYTE_ORDER == BIG_ENDIAN)
1665 di.endian = BFD_ENDIAN_BIG;
1667 di.endian = BFD_ENDIAN_LITTLE;
1669 if (argc != 3 && argc != 4)
1670 error ("wrong # args");
1672 if (strcmp (argv[1], "source") == 0)
1673 mixed_source_and_assembly = 1;
1674 else if (strcmp (argv[1], "nosource") == 0)
1675 mixed_source_and_assembly = 0;
1677 error ("First arg must be 'source' or 'nosource'");
1679 low = parse_and_eval_address (argv[2]);
1683 if (find_pc_partial_function (low, NULL, &low, &high) == 0)
1684 error ("No function contains specified address");
1687 high = parse_and_eval_address (argv[3]);
1689 /* If disassemble_from_exec == -1, then we use the following heuristic to
1690 determine whether or not to do disassembly from target memory or from the
1693 If we're debugging a local process, read target memory, instead of the
1694 exec file. This makes disassembly of functions in shared libs work
1697 Else, we're debugging a remote process, and should disassemble from the
1698 exec file for speed. However, this is no good if the target modifies its
1699 code (for relocation, or whatever).
1702 if (disassemble_from_exec == -1)
1703 if (strcmp (target_shortname, "child") == 0
1704 || strcmp (target_shortname, "procfs") == 0
1705 || strcmp (target_shortname, "vxprocess") == 0)
1706 disassemble_from_exec = 0; /* It's a child process, read inferior mem */
1708 disassemble_from_exec = 1; /* It's remote, read the exec file */
1710 if (disassemble_from_exec)
1711 di.read_memory_func = gdbtk_dis_asm_read_memory;
1713 di.read_memory_func = dis_asm_read_memory;
1715 /* If just doing straight assembly, all we need to do is disassemble
1716 everything between low and high. If doing mixed source/assembly, we've
1717 got a totally different path to follow. */
1719 if (mixed_source_and_assembly)
1720 { /* Come here for mixed source/assembly */
1721 /* The idea here is to present a source-O-centric view of a function to
1722 the user. This means that things are presented in source order, with
1723 (possibly) out of order assembly immediately following. */
1724 struct symtab *symtab;
1725 struct linetable_entry *le;
1728 struct my_line_entry *mle;
1729 struct symtab_and_line sal;
1734 symtab = find_pc_symtab (low); /* Assume symtab is valid for whole PC range */
1739 /* First, convert the linetable to a bunch of my_line_entry's. */
1741 le = symtab->linetable->item;
1742 nlines = symtab->linetable->nitems;
1747 mle = (struct my_line_entry *) alloca (nlines * sizeof (struct my_line_entry));
1751 /* Copy linetable entries for this function into our data structure, creating
1752 end_pc's and setting out_of_order as appropriate. */
1754 /* First, skip all the preceding functions. */
1756 for (i = 0; i < nlines - 1 && le[i].pc < low; i++) ;
1758 /* Now, copy all entries before the end of this function. */
1761 for (; i < nlines - 1 && le[i].pc < high; i++)
1763 if (le[i].line == le[i + 1].line
1764 && le[i].pc == le[i + 1].pc)
1765 continue; /* Ignore duplicates */
1767 mle[newlines].line = le[i].line;
1768 if (le[i].line > le[i + 1].line)
1770 mle[newlines].start_pc = le[i].pc;
1771 mle[newlines].end_pc = le[i + 1].pc;
1775 /* If we're on the last line, and it's part of the function, then we need to
1776 get the end pc in a special way. */
1781 mle[newlines].line = le[i].line;
1782 mle[newlines].start_pc = le[i].pc;
1783 sal = find_pc_line (le[i].pc, 0);
1784 mle[newlines].end_pc = sal.end;
1788 /* Now, sort mle by line #s (and, then by addresses within lines). */
1791 qsort (mle, newlines, sizeof (struct my_line_entry), compare_lines);
1793 /* Now, for each line entry, emit the specified lines (unless they have been
1794 emitted before), followed by the assembly code for that line. */
1796 next_line = 0; /* Force out first line */
1797 for (i = 0; i < newlines; i++)
1799 /* Print out everything from next_line to the current line. */
1801 if (mle[i].line >= next_line)
1804 print_source_lines (symtab, next_line, mle[i].line + 1, 0);
1806 print_source_lines (symtab, mle[i].line, mle[i].line + 1, 0);
1808 next_line = mle[i].line + 1;
1811 for (pc = mle[i].start_pc; pc < mle[i].end_pc; )
1814 fputs_unfiltered (" ", gdb_stdout);
1815 print_address (pc, gdb_stdout);
1816 fputs_unfiltered (":\t ", gdb_stdout);
1817 pc += (*tm_print_insn) (pc, &di);
1818 fputs_unfiltered ("\n", gdb_stdout);
1825 for (pc = low; pc < high; )
1828 fputs_unfiltered (" ", gdb_stdout);
1829 print_address (pc, gdb_stdout);
1830 fputs_unfiltered (":\t ", gdb_stdout);
1831 pc += (*tm_print_insn) (pc, &di);
1832 fputs_unfiltered ("\n", gdb_stdout);
1836 gdb_flush (gdb_stdout);
1842 tk_command (cmd, from_tty)
1848 struct cleanup *old_chain;
1850 /* Catch case of no argument, since this will make the tcl interpreter dump core. */
1852 error_no_arg ("tcl command to interpret");
1854 retval = Tcl_Eval (interp, cmd);
1856 result = strdup (interp->result);
1858 old_chain = make_cleanup (free, result);
1860 if (retval != TCL_OK)
1863 printf_unfiltered ("%s\n", result);
1865 do_cleanups (old_chain);
1869 cleanup_init (ignored)
1873 Tcl_DeleteInterp (interp);
1877 /* Come here during long calculations to check for GUI events. Usually invoked
1878 via the QUIT macro. */
1881 gdbtk_interactive ()
1883 /* Tk_DoOneEvent (TK_DONT_WAIT|TK_IDLE_EVENTS); */
1886 /* Come here when there is activity on the X file descriptor. */
1892 static int in_x_event = 0;
1893 static Tcl_Obj *varname = NULL;
1894 if (in_x_event || in_fputs)
1899 /* Process pending events */
1900 while (Tcl_DoOneEvent (TCL_DONT_WAIT|TCL_ALL_EVENTS) != 0)
1903 if (load_in_progress)
1906 if (varname == NULL)
1908 Tcl_Obj *varnamestrobj = Tcl_NewStringObj("download_cancel_ok",-1);
1909 varname = Tcl_ObjGetVar2(interp,varnamestrobj,NULL,TCL_GLOBAL_ONLY);
1911 if ((Tcl_GetIntFromObj(interp,varname,&val) == TCL_OK) && val)
1925 /* For Cygwin32, we use a timer to periodically check for Windows
1926 messages. FIXME: It would be better to not poll, but to instead
1927 rewrite the target_wait routines to serve as input sources.
1928 Unfortunately, that will be a lot of work. */
1929 static sigset_t nullsigmask;
1930 static struct sigaction act1, act2;
1931 static struct itimerval it_on, it_off;
1934 gdbtk_start_timer ()
1936 static int first = 1;
1937 /*TclDebug ("Starting timer....");*/
1940 /* first time called, set up all the structs */
1942 sigemptyset (&nullsigmask);
1944 act1.sa_handler = x_event;
1945 act1.sa_mask = nullsigmask;
1948 act2.sa_handler = SIG_IGN;
1949 act2.sa_mask = nullsigmask;
1952 it_on.it_interval.tv_sec = 0;
1953 it_on.it_interval.tv_usec = 250000; /* .25 sec */
1954 it_on.it_value.tv_sec = 0;
1955 it_on.it_value.tv_usec = 250000;
1957 it_off.it_interval.tv_sec = 0;
1958 it_off.it_interval.tv_usec = 0;
1959 it_off.it_value.tv_sec = 0;
1960 it_off.it_value.tv_usec = 0;
1963 if (!gdbtk_timer_going)
1965 sigaction (SIGALRM, &act1, NULL);
1966 setitimer (ITIMER_REAL, &it_on, NULL);
1967 gdbtk_timer_going = 1;
1974 if (gdbtk_timer_going)
1976 gdbtk_timer_going = 0;
1977 /*TclDebug ("Stopping timer.");*/
1978 setitimer (ITIMER_REAL, &it_off, NULL);
1979 sigaction (SIGALRM, &act2, NULL);
1983 /* This hook function is called whenever we want to wait for the
1987 gdbtk_wait (pid, ourstatus)
1989 struct target_waitstatus *ourstatus;
1991 gdbtk_start_timer ();
1992 pid = target_wait (pid, ourstatus);
1993 gdbtk_stop_timer ();
1997 /* This is called from execute_command, and provides a wrapper around
1998 various command routines in a place where both protocol messages and
1999 user input both flow through. Mostly this is used for indicating whether
2000 the target process is running or not.
2004 gdbtk_call_command (cmdblk, arg, from_tty)
2005 struct cmd_list_element *cmdblk;
2010 if (cmdblk->class == class_run || cmdblk->class == class_trace)
2013 /* HACK! HACK! This is to get the gui to update the tstart/tstop
2014 button only incase of tstart/tstop commands issued from the console
2015 We don't want to update the src window, s we need to have specific
2016 procedures to do tstart and tstop
2018 if (!strcmp(cmdblk->name, "tstart") && !No_Update)
2019 Tcl_Eval (interp, "gdbtk_tcl_tstart");
2020 else if (!strcmp(cmdblk->name, "tstop") && !No_Update)
2021 Tcl_Eval (interp, "gdbtk_tcl_tstop");
2027 Tcl_Eval (interp, "gdbtk_tcl_busy");
2028 (*cmdblk->function.cfunc)(arg, from_tty);
2031 Tcl_Eval (interp, "gdbtk_tcl_idle");
2035 (*cmdblk->function.cfunc)(arg, from_tty);
2038 /* This function is called instead of gdb's internal command loop. This is the
2039 last chance to do anything before entering the main Tk event loop. */
2044 extern GDB_FILE *instream;
2046 /* We no longer want to use stdin as the command input stream */
2049 if (Tcl_Eval (interp, "gdbtk_tcl_preloop") != TCL_OK)
2053 /* Force errorInfo to be set up propertly. */
2054 Tcl_AddErrorInfo (interp, "");
2056 msg = Tcl_GetVar (interp, "errorInfo", TCL_GLOBAL_ONLY);
2058 MessageBox (NULL, msg, NULL, MB_OK | MB_ICONERROR | MB_TASKMODAL);
2060 fputs_unfiltered (msg, gdb_stderr);
2071 /* gdbtk_init installs this function as a final cleanup. */
2074 gdbtk_cleanup (dummy)
2078 struct ide_event_handle *h = (struct ide_event_handle *) dummy;
2080 ide_interface_deregister_all (h);
2085 /* Initialize gdbtk. */
2088 gdbtk_init ( argv0 )
2091 struct cleanup *old_chain;
2092 char *lib, *gdbtk_lib, *gdbtk_lib_tmp, *gdbtk_file;
2095 struct sigaction action;
2096 static sigset_t nullsigmask = {0};
2099 /* start-sanitize-ide */
2100 struct ide_event_handle *h;
2103 /* end-sanitize-ide */
2106 /* If there is no DISPLAY environment variable, Tk_Init below will fail,
2107 causing gdb to abort. If instead we simply return here, gdb will
2108 gracefully degrade to using the command line interface. */
2111 if (getenv ("DISPLAY") == NULL)
2115 old_chain = make_cleanup (cleanup_init, 0);
2117 /* First init tcl and tk. */
2118 Tcl_FindExecutable (argv0);
2119 interp = Tcl_CreateInterp ();
2121 #ifdef TCL_MEM_DEBUG
2122 Tcl_InitMemory (interp);
2126 error ("Tcl_CreateInterp failed");
2128 if (Tcl_Init(interp) != TCL_OK)
2129 error ("Tcl_Init failed: %s", interp->result);
2132 /* For the IDE we register the cleanup later, after we've
2133 initialized events. */
2134 make_final_cleanup (gdbtk_cleanup, NULL);
2137 /* Initialize the Paths variable. */
2138 if (ide_initialize_paths (interp, "gdbtcl") != TCL_OK)
2139 error ("ide_initialize_paths failed: %s", interp->result);
2142 /* start-sanitize-ide */
2143 /* Find the directory where we expect to find idemanager. We ignore
2144 errors since it doesn't really matter if this fails. */
2145 libexecdir = Tcl_GetVar2 (interp, "Paths", "libexecdir", TCL_GLOBAL_ONLY);
2149 h = ide_event_init_from_environment (&errmsg, libexecdir);
2150 make_final_cleanup (gdbtk_cleanup, h);
2153 Tcl_AppendResult (interp, "can't initialize event system: ", errmsg,
2155 fprintf(stderr, "WARNING: ide_event_init_client failed: %s\n", interp->result);
2157 Tcl_SetVar (interp, "GDBTK_IDE", "0", 0);
2161 if (ide_create_tclevent_command (interp, h) != TCL_OK)
2162 error ("ide_create_tclevent_command failed: %s", interp->result);
2164 if (ide_create_edit_command (interp, h) != TCL_OK)
2165 error ("ide_create_edit_command failed: %s", interp->result);
2167 if (ide_create_property_command (interp, h) != TCL_OK)
2168 error ("ide_create_property_command failed: %s", interp->result);
2170 if (ide_create_build_command (interp, h) != TCL_OK)
2171 error ("ide_create_build_command failed: %s", interp->result);
2173 if (ide_create_window_register_command (interp, h, "gdb-restore")
2175 error ("ide_create_window_register_command failed: %s",
2178 if (ide_create_window_command (interp, h) != TCL_OK)
2179 error ("ide_create_window_command failed: %s", interp->result);
2181 if (ide_create_exit_command (interp, h) != TCL_OK)
2182 error ("ide_create_exit_command failed: %s", interp->result);
2184 if (ide_create_help_command (interp) != TCL_OK)
2185 error ("ide_create_help_command failed: %s", interp->result);
2188 if (ide_initialize (interp, "gdb") != TCL_OK)
2189 error ("ide_initialize failed: %s", interp->result);
2192 Tcl_SetVar (interp, "GDBTK_IDE", "1", 0);
2194 /* end-sanitize-ide */
2196 Tcl_SetVar (interp, "GDBTK_IDE", "0", 0);
2199 /* We don't want to open the X connection until we've done all the
2200 IDE initialization. Otherwise, goofy looking unfinished windows
2201 pop up when ILU drops into the TCL event loop. */
2203 if (Tk_Init(interp) != TCL_OK)
2204 error ("Tk_Init failed: %s", interp->result);
2206 if (Itcl_Init(interp) == TCL_ERROR)
2207 error ("Itcl_Init failed: %s", interp->result);
2209 if (Tix_Init(interp) != TCL_OK)
2210 error ("Tix_Init failed: %s", interp->result);
2213 if (ide_create_messagebox_command (interp) != TCL_OK)
2214 error ("messagebox command initialization failed");
2215 /* On Windows, create a sizebox widget command */
2216 if (ide_create_sizebox_command (interp) != TCL_OK)
2217 error ("sizebox creation failed");
2218 if (ide_create_winprint_command (interp) != TCL_OK)
2219 error ("windows print code initialization failed");
2220 /* start-sanitize-ide */
2221 /* An interface to ShellExecute. */
2222 if (ide_create_shell_execute_command (interp) != TCL_OK)
2223 error ("shell execute command initialization failed");
2224 /* end-sanitize-ide */
2225 if (ide_create_win_grab_command (interp) != TCL_OK)
2226 error ("grab support command initialization failed");
2227 /* Path conversion functions. */
2228 if (ide_create_cygwin_path_command (interp) != TCL_OK)
2229 error ("cygwin path command initialization failed");
2232 Tcl_CreateCommand (interp, "gdb_cmd", call_wrapper, gdb_cmd, NULL);
2233 Tcl_CreateCommand (interp, "gdb_immediate", call_wrapper,
2234 gdb_immediate_command, NULL);
2235 Tcl_CreateCommand (interp, "gdb_loc", call_wrapper, gdb_loc, NULL);
2236 Tcl_CreateCommand (interp, "gdb_path_conv", call_wrapper, gdb_path_conv, NULL);
2237 Tcl_CreateObjCommand (interp, "gdb_listfiles", call_obj_wrapper, gdb_listfiles, NULL);
2238 Tcl_CreateCommand (interp, "gdb_listfuncs", call_wrapper, gdb_listfuncs,
2240 Tcl_CreateCommand (interp, "gdb_get_mem", call_wrapper, gdb_get_mem,
2242 Tcl_CreateCommand (interp, "gdb_stop", call_wrapper, gdb_stop, NULL);
2243 Tcl_CreateCommand (interp, "gdb_regnames", call_wrapper, gdb_regnames, NULL);
2244 Tcl_CreateCommand (interp, "gdb_fetch_registers", call_wrapper,
2245 gdb_fetch_registers, NULL);
2246 Tcl_CreateCommand (interp, "gdb_changed_register_list", call_wrapper,
2247 gdb_changed_register_list, NULL);
2248 Tcl_CreateCommand (interp, "gdb_disassemble", call_wrapper,
2249 gdb_disassemble, NULL);
2250 Tcl_CreateCommand (interp, "gdb_eval", call_wrapper, gdb_eval, NULL);
2251 Tcl_CreateCommand (interp, "gdb_get_breakpoint_list", call_wrapper,
2252 gdb_get_breakpoint_list, NULL);
2253 Tcl_CreateCommand (interp, "gdb_get_breakpoint_info", call_wrapper,
2254 gdb_get_breakpoint_info, NULL);
2255 Tcl_CreateCommand (interp, "gdb_clear_file", call_wrapper,
2256 gdb_clear_file, NULL);
2257 Tcl_CreateCommand (interp, "gdb_confirm_quit", call_wrapper,
2258 gdb_confirm_quit, NULL);
2259 Tcl_CreateCommand (interp, "gdb_force_quit", call_wrapper,
2260 gdb_force_quit, NULL);
2261 Tcl_CreateCommand (interp, "gdb_target_has_execution",
2262 gdb_target_has_execution_command,
2264 Tcl_CreateCommand (interp, "gdb_is_tracing",
2267 Tcl_CreateObjCommand (interp, "gdb_load_info", call_obj_wrapper, gdb_load_info, NULL);
2268 Tcl_CreateObjCommand (interp, "gdb_get_locals", call_obj_wrapper, gdb_get_locals_command,
2270 Tcl_CreateObjCommand (interp, "gdb_get_args", call_obj_wrapper, gdb_get_args_command,
2272 Tcl_CreateObjCommand (interp, "gdb_get_function", call_obj_wrapper, gdb_get_function_command,
2274 Tcl_CreateObjCommand (interp, "gdb_get_line", call_obj_wrapper, gdb_get_line_command,
2276 Tcl_CreateObjCommand (interp, "gdb_get_file", call_obj_wrapper, gdb_get_file_command,
2278 Tcl_CreateObjCommand (interp, "gdb_tracepoint_exists",
2279 call_obj_wrapper, gdb_tracepoint_exists_command, NULL);
2280 Tcl_CreateObjCommand (interp, "gdb_get_tracepoint_info",
2281 call_obj_wrapper, gdb_get_tracepoint_info, NULL);
2282 Tcl_CreateObjCommand (interp, "gdb_actions",
2283 call_obj_wrapper, gdb_actions_command, NULL);
2284 Tcl_CreateObjCommand (interp, "gdb_prompt",
2285 call_obj_wrapper, gdb_prompt_command, NULL);
2286 Tcl_CreateObjCommand (interp, "gdb_find_file",
2287 call_obj_wrapper, gdb_find_file_command, NULL);
2288 Tcl_CreateObjCommand (interp, "gdb_get_tracepoint_list",
2289 call_obj_wrapper, gdb_get_tracepoint_list, NULL);
2290 Tcl_CreateCommand (interp, "gdb_pc_reg", get_pc_register, NULL, NULL);
2291 Tcl_CreateObjCommand (interp, "gdb_loadfile", call_obj_wrapper, gdb_loadfile, NULL);
2292 Tcl_CreateObjCommand (interp, "gdb_set_bp", call_obj_wrapper, gdb_set_bp, NULL);
2294 command_loop_hook = tk_command_loop;
2295 print_frame_info_listing_hook = gdbtk_print_frame_info;
2296 query_hook = gdbtk_query;
2297 warning_hook = gdbtk_warning;
2298 flush_hook = gdbtk_flush;
2299 create_breakpoint_hook = gdbtk_create_breakpoint;
2300 delete_breakpoint_hook = gdbtk_delete_breakpoint;
2301 modify_breakpoint_hook = gdbtk_modify_breakpoint;
2302 interactive_hook = gdbtk_interactive;
2303 target_wait_hook = gdbtk_wait;
2304 call_command_hook = gdbtk_call_command;
2305 readline_begin_hook = gdbtk_readline_begin;
2306 readline_hook = gdbtk_readline;
2307 readline_end_hook = gdbtk_readline_end;
2308 ui_load_progress_hook = gdbtk_load_hash;
2309 pre_add_symbol_hook = gdbtk_pre_add_symbol;
2310 post_add_symbol_hook = gdbtk_post_add_symbol;
2311 create_tracepoint_hook = gdbtk_create_tracepoint;
2312 delete_tracepoint_hook = gdbtk_delete_tracepoint;
2313 modify_tracepoint_hook = gdbtk_modify_tracepoint;
2314 pc_changed_hook = pc_changed;
2316 add_com ("tk", class_obscure, tk_command,
2317 "Send a command directly into tk.");
2319 Tcl_LinkVar (interp, "disassemble-from-exec", (char *)&disassemble_from_exec,
2322 /* find the gdb tcl library and source main.tcl */
2324 gdbtk_lib = getenv ("GDBTK_LIBRARY");
2326 if (access ("gdbtcl/main.tcl", R_OK) == 0)
2327 gdbtk_lib = "gdbtcl";
2329 gdbtk_lib = GDBTK_LIBRARY;
2331 gdbtk_lib_tmp = xstrdup (gdbtk_lib);
2334 /* see if GDBTK_LIBRARY is a path list */
2335 lib = strtok (gdbtk_lib_tmp, GDBTK_PATH_SEP);
2338 if (Tcl_VarEval (interp, "lappend auto_path ", lib, NULL) != TCL_OK)
2340 fputs_unfiltered (Tcl_GetVar (interp, "errorInfo", 0), gdb_stderr);
2345 gdbtk_file = concat (lib, "/main.tcl", (char *) NULL);
2346 if (access (gdbtk_file, R_OK) == 0)
2349 Tcl_SetVar (interp, "GDBTK_LIBRARY", lib, 0);
2353 while ((lib = strtok (NULL, ":")) != NULL);
2355 free (gdbtk_lib_tmp);
2359 /* Try finding it with the auto path. */
2361 static const char script[] ="\
2362 proc gdbtk_find_main {} {\n\
2363 global auto_path GDBTK_LIBRARY\n\
2364 foreach dir $auto_path {\n\
2365 set f [file join $dir main.tcl]\n\
2366 if {[file exists $f]} then {\n\
2367 set GDBTK_LIBRARY $dir\n\
2375 if (Tcl_GlobalEval (interp, (char *) script) != TCL_OK)
2377 fputs_unfiltered (Tcl_GetVar (interp, "errorInfo", 0), gdb_stderr);
2381 if (interp->result[0] != '\0')
2383 gdbtk_file = xstrdup (interp->result);
2390 fputs_unfiltered_hook = NULL; /* Force errors to stdout/stderr */
2391 if (getenv("GDBTK_LIBRARY"))
2393 fprintf_unfiltered (stderr, "Unable to find main.tcl in %s\n",getenv("GDBTK_LIBRARY"));
2394 fprintf_unfiltered (stderr,
2395 "Please set GDBTK_LIBRARY to a path that includes the GDB tcl files.\n");
2399 fprintf_unfiltered (stderr, "Unable to find main.tcl in %s\n", GDBTK_LIBRARY);
2400 fprintf_unfiltered (stderr, "You might want to set GDBTK_LIBRARY\n");
2405 /* Defer setup of fputs_unfiltered_hook to near the end so that error messages
2406 prior to this point go to stdout/stderr. */
2408 fputs_unfiltered_hook = gdbtk_fputs;
2410 if (Tcl_EvalFile (interp, gdbtk_file) != TCL_OK)
2414 /* Force errorInfo to be set up propertly. */
2415 Tcl_AddErrorInfo (interp, "");
2417 msg = Tcl_GetVar (interp, "errorInfo", TCL_GLOBAL_ONLY);
2419 fputs_unfiltered_hook = NULL; /* Force errors to stdout/stderr */
2422 MessageBox (NULL, msg, NULL, MB_OK | MB_ICONERROR | MB_TASKMODAL);
2424 fputs_unfiltered (msg, gdb_stderr);
2431 /* start-sanitize-ide */
2432 /* Don't do this until we have initialized. Otherwise, we may get a
2433 run command before we are ready for one. */
2434 if (ide_run_server_init (interp, h) != TCL_OK)
2435 error ("ide_run_server_init failed: %s", interp->result);
2436 /* end-sanitize-ide */
2441 discard_cleanups (old_chain);
2445 gdb_target_has_execution_command (clientData, interp, argc, argv)
2446 ClientData clientData;
2453 if (target_has_execution && inferior_pid != 0)
2456 Tcl_SetIntObj (Tcl_GetObjResult (interp), result);
2461 gdb_trace_status (clientData, interp, argc, argv)
2462 ClientData clientData;
2469 if (trace_running_p)
2472 Tcl_SetIntObj (Tcl_GetObjResult (interp), result);
2476 /* gdb_load_info - returns information about the file about to be downloaded */
2479 gdb_load_info (clientData, interp, objc, objv)
2480 ClientData clientData;
2483 Tcl_Obj *CONST objv[];
2486 struct cleanup *old_cleanups;
2492 char *filename = Tcl_GetStringFromObj (objv[1], NULL);
2494 loadfile_bfd = bfd_openr (filename, gnutarget);
2495 if (loadfile_bfd == NULL)
2497 Tcl_SetObjResult (interp, Tcl_NewStringObj ("Open failed", -1));
2500 old_cleanups = make_cleanup (bfd_close, loadfile_bfd);
2502 if (!bfd_check_format (loadfile_bfd, bfd_object))
2504 Tcl_SetObjResult (interp, Tcl_NewStringObj ("Bad Object File", -1));
2508 for (s = loadfile_bfd->sections; s; s = s->next)
2510 if (s->flags & SEC_LOAD)
2512 bfd_size_type size = bfd_get_section_size_before_reloc (s);
2515 ob[0] = Tcl_NewStringObj((char *)bfd_get_section_name(loadfile_bfd, s), -1);
2516 ob[1] = Tcl_NewLongObj ((long)size);
2517 res[i++] = Tcl_NewListObj (2, ob);
2522 Tcl_SetObjResult (interp, Tcl_NewListObj (i, res));
2523 do_cleanups (old_cleanups);
2529 gdbtk_load_hash (section, num)
2534 sprintf (buf, "download_hash %s %ld", section, num);
2535 Tcl_Eval (interp, buf);
2536 return atoi (interp->result);
2540 * This and gdb_get_locals just call gdb_get_vars_command with the right
2541 * value of clientData. We can't use the client data in the definition
2542 * of the command, because the call wrapper uses this instead...
2546 gdb_get_locals_command (clientData, interp, objc, objv)
2547 ClientData clientData;
2550 Tcl_Obj *CONST objv[];
2553 return gdb_get_vars_command((ClientData) 0, interp, objc, objv);
2558 gdb_get_args_command (clientData, interp, objc, objv)
2559 ClientData clientData;
2562 Tcl_Obj *CONST objv[];
2565 return gdb_get_vars_command((ClientData) 1, interp, objc, objv);
2569 /* gdb_get_vars_command -
2571 * Implements the "gdb_get_locals" and "gdb_get_args" tcl commands. This
2572 * function sets the Tcl interpreter's result to a list of variable names
2573 * depending on clientData. If clientData is one, the result is a list of
2574 * arguments; zero returns a list of locals -- all relative to the block
2575 * specified as an argument to the command. Valid commands include
2576 * anything decode_line_1 can handle (like "main.c:2", "*0x02020202",
2580 gdb_get_vars_command (clientData, interp, objc, objv)
2581 ClientData clientData;
2584 Tcl_Obj *CONST objv[];
2587 struct symtabs_and_lines sals;
2589 struct block *block;
2590 char **canonical, *args;
2591 int i, nsyms, arguments;
2595 Tcl_AppendResult (interp,
2596 "wrong # of args: should be \"",
2597 Tcl_GetStringFromObj (objv[0], NULL),
2598 " function:line|function|line|*addr\"");
2602 arguments = (int) clientData;
2603 args = Tcl_GetStringFromObj (objv[1], NULL);
2604 sals = decode_line_1 (&args, 1, NULL, 0, &canonical);
2605 if (sals.nelts == 0)
2607 Tcl_AppendResult (interp,
2608 "error decoding line", NULL);
2612 /* Initialize a list that will hold the results */
2613 result = Tcl_NewListObj (0, NULL);
2615 /* Resolve all line numbers to PC's */
2616 for (i = 0; i < sals.nelts; i++)
2617 resolve_sal_pc (&sals.sals[i]);
2619 block = block_for_pc (sals.sals[0].pc);
2622 nsyms = BLOCK_NSYMS (block);
2623 for (i = 0; i < nsyms; i++)
2625 sym = BLOCK_SYM (block, i);
2626 switch (SYMBOL_CLASS (sym)) {
2628 case LOC_UNDEF: /* catches errors */
2629 case LOC_CONST: /* constant */
2630 case LOC_STATIC: /* static */
2631 case LOC_REGISTER: /* register */
2632 case LOC_TYPEDEF: /* local typedef */
2633 case LOC_LABEL: /* local label */
2634 case LOC_BLOCK: /* local function */
2635 case LOC_CONST_BYTES: /* loc. byte seq. */
2636 case LOC_UNRESOLVED: /* unresolved static */
2637 case LOC_OPTIMIZED_OUT: /* optimized out */
2639 case LOC_ARG: /* argument */
2640 case LOC_REF_ARG: /* reference arg */
2641 case LOC_REGPARM: /* register arg */
2642 case LOC_REGPARM_ADDR: /* indirect register arg */
2643 case LOC_LOCAL_ARG: /* stack arg */
2644 case LOC_BASEREG_ARG: /* basereg arg */
2646 Tcl_ListObjAppendElement (interp, result,
2647 Tcl_NewStringObj (SYMBOL_NAME (sym), -1));
2649 case LOC_LOCAL: /* stack local */
2650 case LOC_BASEREG: /* basereg local */
2652 Tcl_ListObjAppendElement (interp, result,
2653 Tcl_NewStringObj (SYMBOL_NAME (sym), -1));
2657 if (BLOCK_FUNCTION (block))
2660 block = BLOCK_SUPERBLOCK (block);
2663 Tcl_SetObjResult (interp, result);
2668 gdb_get_line_command (clientData, interp, objc, objv)
2669 ClientData clientData;
2672 Tcl_Obj *CONST objv[];
2675 struct symtabs_and_lines sals;
2676 char *args, **canonical;
2680 Tcl_AppendResult (interp, "wrong # of args: should be \"",
2681 Tcl_GetStringFromObj (objv[0], NULL),
2686 args = Tcl_GetStringFromObj (objv[1], NULL);
2687 sals = decode_line_1 (&args, 1, NULL, 0, &canonical);
2688 if (sals.nelts == 1)
2690 Tcl_SetObjResult (interp, Tcl_NewIntObj (sals.sals[0].line));
2694 Tcl_SetResult (interp, "N/A", TCL_STATIC);
2699 gdb_get_file_command (clientData, interp, objc, objv)
2700 ClientData clientData;
2703 Tcl_Obj *CONST objv[];
2706 struct symtabs_and_lines sals;
2707 char *args, **canonical;
2711 Tcl_AppendResult (interp, "wrong # of args: should be \"",
2712 Tcl_GetStringFromObj (objv[0], NULL),
2717 args = Tcl_GetStringFromObj (objv[1], NULL);
2718 sals = decode_line_1 (&args, 1, NULL, 0, &canonical);
2719 if (sals.nelts == 1)
2721 Tcl_SetResult (interp, sals.sals[0].symtab->filename, TCL_VOLATILE);
2725 Tcl_SetResult (interp, "N/A", TCL_STATIC);
2730 gdb_get_function_command (clientData, interp, objc, objv)
2731 ClientData clientData;
2734 Tcl_Obj *CONST objv[];
2738 struct symtabs_and_lines sals;
2739 char *args, **canonical;
2743 Tcl_AppendResult (interp, "wrong # of args: should be \"",
2744 Tcl_GetStringFromObj (objv[0], NULL),
2749 args = Tcl_GetStringFromObj (objv[1], NULL);
2750 sals = decode_line_1 (&args, 1, NULL, 0, &canonical);
2751 if (sals.nelts == 1)
2753 resolve_sal_pc (&sals.sals[0]);
2754 find_pc_partial_function (sals.sals[0].pc, &function, NULL, NULL);
2755 if (function != NULL)
2757 Tcl_SetResult (interp, function, TCL_VOLATILE);
2762 Tcl_SetResult (interp, "N/A", TCL_STATIC);
2767 gdb_get_tracepoint_info (clientData, interp, objc, objv)
2768 ClientData clientData;
2771 Tcl_Obj *CONST objv[];
2773 struct symtab_and_line sal;
2775 struct tracepoint *tp;
2776 struct action_line *al;
2777 Tcl_Obj *list, *action_list;
2778 char *filename, *funcname;
2782 error ("wrong # args");
2784 Tcl_GetIntFromObj (NULL, objv[1], &tpnum);
2786 ALL_TRACEPOINTS (tp)
2787 if (tp->number == tpnum)
2791 error ("Tracepoint #%d does not exist", tpnum);
2793 list = Tcl_NewListObj (0, NULL);
2794 sal = find_pc_line (tp->address, 0);
2795 filename = symtab_to_filename (sal.symtab);
2796 if (filename == NULL)
2798 Tcl_ListObjAppendElement (interp, list,
2799 Tcl_NewStringObj (filename, -1));
2800 find_pc_partial_function (tp->address, &funcname, NULL, NULL);
2801 Tcl_ListObjAppendElement (interp, list, Tcl_NewStringObj (funcname, -1));
2802 Tcl_ListObjAppendElement (interp, list, Tcl_NewIntObj (sal.line));
2803 sprintf (tmp, "0x%lx", tp->address);
2804 Tcl_ListObjAppendElement (interp, list, Tcl_NewStringObj (tmp, -1));
2805 Tcl_ListObjAppendElement (interp, list, Tcl_NewIntObj (tp->enabled));
2806 Tcl_ListObjAppendElement (interp, list, Tcl_NewIntObj (tp->pass_count));
2807 Tcl_ListObjAppendElement (interp, list, Tcl_NewIntObj (tp->step_count));
2808 Tcl_ListObjAppendElement (interp, list, Tcl_NewIntObj (tp->thread));
2809 Tcl_ListObjAppendElement (interp, list, Tcl_NewIntObj (tp->hit_count));
2811 /* Append a list of actions */
2812 action_list = Tcl_NewListObj (0, NULL);
2813 for (al = tp->actions; al != NULL; al = al->next)
2815 Tcl_ListObjAppendElement (interp, action_list,
2816 Tcl_NewStringObj (al->action, -1));
2818 Tcl_ListObjAppendElement (interp, list, action_list);
2820 Tcl_SetObjResult (interp, list);
2825 /* TclDebug (const char *fmt, ...) works just like printf() but */
2826 /* sends the output to the GDB TK debug window. */
2827 /* Not for normal use; just a convenient tool for debugging */
2829 #ifdef ANSI_PROTOTYPES
2830 TclDebug (const char *fmt, ...)
2837 char buf[512], *v[2], *merge;
2839 #ifdef ANSI_PROTOTYPES
2840 va_start (args, fmt);
2844 fmt = va_arg (args, char *);
2850 vsprintf (buf, fmt, args);
2853 merge = Tcl_Merge (2, v);
2854 Tcl_Eval (interp, merge);
2859 /* Find the full pathname to a file, searching the symbol tables */
2862 gdb_find_file_command (clientData, interp, objc, objv)
2863 ClientData clientData;
2866 Tcl_Obj *CONST objv[];
2868 char *filename = NULL;
2873 Tcl_WrongNumArgs(interp, 1, objv, "filename");
2877 st = full_lookup_symtab (Tcl_GetStringFromObj (objv[1], NULL));
2879 filename = st->fullname;
2881 if (filename == NULL)
2882 Tcl_SetObjResult (interp, Tcl_NewStringObj ("", 0));
2884 Tcl_SetObjResult (interp, Tcl_NewStringObj (filename, -1));
2890 gdbtk_create_tracepoint (tp)
2891 struct tracepoint *tp;
2893 tracepoint_notify (tp, "create");
2897 gdbtk_delete_tracepoint (tp)
2898 struct tracepoint *tp;
2900 tracepoint_notify (tp, "delete");
2904 gdbtk_modify_tracepoint (tp)
2905 struct tracepoint *tp;
2907 tracepoint_notify (tp, "modify");
2911 tracepoint_notify(tp, action)
2912 struct tracepoint *tp;
2917 struct symtab_and_line sal;
2920 /* We ensure that ACTION contains no special Tcl characters, so we
2922 sal = find_pc_line (tp->address, 0);
2924 filename = symtab_to_filename (sal.symtab);
2925 if (filename == NULL)
2927 sprintf (buf, "gdbtk_tcl_tracepoint %s %d 0x%lx %d {%s}", action, tp->number,
2928 (long)tp->address, sal.line, filename, tp->pass_count);
2930 v = Tcl_Eval (interp, buf);
2934 gdbtk_fputs (interp->result, gdb_stdout);
2935 gdbtk_fputs ("\n", gdb_stdout);
2939 /* returns -1 if not found, tracepoint # if found */
2941 tracepoint_exists (char * args)
2943 struct tracepoint *tp;
2945 struct symtabs_and_lines sals;
2949 sals = decode_line_1 (&args, 1, NULL, 0, &canonical);
2950 if (sals.nelts == 1)
2952 resolve_sal_pc (&sals.sals[0]);
2953 file = xmalloc (strlen (sals.sals[0].symtab->dirname)
2954 + strlen (sals.sals[0].symtab->filename) + 1);
2957 strcpy (file, sals.sals[0].symtab->dirname);
2958 strcat (file, sals.sals[0].symtab->filename);
2960 ALL_TRACEPOINTS (tp)
2962 if (tp->address == sals.sals[0].pc)
2963 result = tp->number;
2965 /* Why is this here? This messes up assembly traces */
2966 else if (tp->source_file != NULL
2967 && strcmp (tp->source_file, file) == 0
2968 && sals.sals[0].line == tp->line_number)
2969 result = tp->number;
2980 gdb_actions_command (clientData, interp, objc, objv)
2981 ClientData clientData;
2984 Tcl_Obj *CONST objv[];
2986 struct tracepoint *tp;
2988 int nactions, i, len;
2989 char *number, *args, *action;
2991 struct action_line *next = NULL, *temp;
2995 Tcl_AppendResult (interp, "wrong # args: should be: \"",
2996 Tcl_GetStringFromObj (objv[0], NULL),
2997 " number actions\"");
3001 args = number = Tcl_GetStringFromObj (objv[1], NULL);
3002 tp = get_tracepoint_by_number (&args);
3005 Tcl_AppendResult (interp, "Tracepoint \"", number, "\" does not exist");
3009 /* Free any existing actions */
3010 if (tp->actions != NULL)
3015 Tcl_ListObjGetElements (interp, objv[2], &nactions, &actions);
3016 for (i = 0; i < nactions; i++)
3018 temp = xmalloc (sizeof (struct action_line));
3020 action = Tcl_GetStringFromObj (actions[i], &len);
3021 temp->action = savestring (action, len);
3022 if (sscanf (temp->action, "while-stepping %d", &step_count) !=0)
3023 tp->step_count = step_count;
3040 gdb_tracepoint_exists_command (clientData, interp, objc, objv)
3041 ClientData clientData;
3044 Tcl_Obj *CONST objv[];
3050 Tcl_AppendResult (interp, "wrong # of args: should be \"",
3051 Tcl_GetStringFromObj (objv[0], NULL),
3052 " function:line|function|line|*addr\"");
3056 args = Tcl_GetStringFromObj (objv[1], NULL);
3058 Tcl_SetObjResult (interp, Tcl_NewIntObj (tracepoint_exists (args)));
3062 /* Return the prompt to the interpreter */
3064 gdb_prompt_command (clientData, interp, objc, objv)
3065 ClientData clientData;
3068 Tcl_Obj *CONST objv[];
3070 Tcl_SetResult (interp, get_prompt (), TCL_VOLATILE);
3074 /* return a list of all tracepoint numbers in interpreter */
3076 gdb_get_tracepoint_list (clientData, interp, objc, objv)
3077 ClientData clientData;
3080 Tcl_Obj *CONST objv[];
3083 struct tracepoint *tp;
3085 list = Tcl_NewListObj (0, NULL);
3087 ALL_TRACEPOINTS (tp)
3088 Tcl_ListObjAppendElement (interp, list, Tcl_NewIntObj (tp->number));
3090 Tcl_SetObjResult (interp, list);
3095 /* This hook is called whenever we are ready to load a symbol file so that
3096 the UI can notify the user... */
3098 gdbtk_pre_add_symbol (name)
3103 v[0] = "gdbtk_tcl_pre_add_symbol";
3105 merge = Tcl_Merge (2, v);
3106 Tcl_Eval (interp, merge);
3110 /* This hook is called whenever we finish loading a symbol file. */
3112 gdbtk_post_add_symbol ()
3114 Tcl_Eval (interp, "gdbtk_tcl_post_add_symbol");
3120 gdbtk_print_frame_info (s, line, stopline, noerror)
3126 current_source_symtab = s;
3127 current_source_line = line;
3131 /* The lookup_symtab() in symtab.c doesn't work correctly */
3132 /* It will not work will full pathnames and if multiple */
3133 /* source files have the same basename, it will return */
3134 /* the first one instead of the correct one. This version */
3135 /* also always makes sure symtab->fullname is set. */
3137 static struct symtab *
3138 full_lookup_symtab(file)
3142 struct objfile *objfile;
3143 char *bfile, *fullname;
3144 struct partial_symtab *pt;
3149 /* first try a direct lookup */
3150 st = lookup_symtab (file);
3154 symtab_to_filename(st);
3158 /* if the direct approach failed, try */
3159 /* looking up the basename and checking */
3160 /* all matches with the fullname */
3161 bfile = basename (file);
3162 ALL_SYMTABS (objfile, st)
3164 if (!strcmp (bfile, basename(st->filename)))
3167 fullname = symtab_to_filename (st);
3169 fullname = st->fullname;
3171 if (!strcmp (file, fullname))
3176 /* still no luck? look at psymtabs */
3177 ALL_PSYMTABS (objfile, pt)
3179 if (!strcmp (bfile, basename(pt->filename)))
3181 st = PSYMTAB_TO_SYMTAB (pt);
3184 fullname = symtab_to_filename (st);
3185 if (!strcmp (file, fullname))
3194 perror_with_name_wrapper (args)
3197 perror_with_name (args);
3201 /* gdb_loadfile loads a c source file into a text widget. */
3203 /* LTABLE_SIZE is the number of bytes to allocate for the */
3204 /* line table. Its size limits the maximum number of lines */
3205 /* in a file to 8 * LTABLE_SIZE. This memory is freed after */
3206 /* the file is loaded, so it is OK to make this very large. */
3207 /* Additional memory will be allocated if needed. */
3208 #define LTABLE_SIZE 20000
3211 gdb_loadfile (clientData, interp, objc, objv)
3212 ClientData clientData;
3215 Tcl_Obj *CONST objv[];
3217 char *file, *widget, *line, *buf, msg[128];
3218 int linenumbers, ln, anum, lnum, ltable_size;
3219 Tcl_Obj *a[2], *b[2], *cmd;
3222 struct symtab *symtab;
3223 struct linetable_entry *le;
3230 Tcl_WrongNumArgs(interp, 1, objv, "widget filename linenumbers");
3234 widget = Tcl_GetStringFromObj (objv[1], NULL);
3235 file = Tcl_GetStringFromObj (objv[2], NULL);
3236 Tcl_GetBooleanFromObj (interp, objv[3], &linenumbers);
3238 if ((fp = fopen ( file, "r" )) == NULL)
3241 symtab = full_lookup_symtab (file);
3244 sprintf(msg, "File not found");
3245 Tcl_SetStringObj ( Tcl_GetObjResult (interp), msg, -1);
3250 if (stat (file, &st) < 0)
3252 catch_errors (perror_with_name_wrapper, "gdbtk: get time stamp", "",
3257 if (symtab && symtab->objfile && symtab->objfile->obfd)
3258 mtime = bfd_get_mtime(symtab->objfile->obfd);
3260 mtime = bfd_get_mtime(exec_bfd);
3262 if (mtime && mtime < st.st_mtime)
3263 gdbtk_ignorable_warning("Source file is more recent than executable.\n", (va_list)0);
3266 /* Source linenumbers don't appear to be in order, and a sort is */
3267 /* too slow so the fastest solution is just to allocate a huge */
3268 /* array and set the array entry for each linenumber */
3270 ltable_size = LTABLE_SIZE;
3271 ltable = (char *)malloc (LTABLE_SIZE);
3274 sprintf(msg, "Out of memory.");
3275 Tcl_SetStringObj ( Tcl_GetObjResult (interp), msg, -1);
3280 memset (ltable, 0, LTABLE_SIZE);
3282 if (symtab->linetable && symtab->linetable->nitems)
3284 le = symtab->linetable->item;
3285 for (ln = symtab->linetable->nitems ;ln > 0; ln--, le++)
3287 lnum = le->line >> 3;
3288 if (lnum >= ltable_size)
3291 new_ltable = (char *)realloc (ltable, ltable_size*2);
3292 memset (new_ltable + ltable_size, 0, ltable_size);
3294 if (new_ltable == NULL)
3296 sprintf(msg, "Out of memory.");
3297 Tcl_SetStringObj ( Tcl_GetObjResult (interp), msg, -1);
3302 ltable = new_ltable;
3304 ltable[lnum] |= 1 << (le->line % 8);
3308 /* create an object with enough space, then grab its */
3309 /* buffer and sprintf directly into it. */
3310 a[0] = Tcl_NewStringObj (ltable, 1024);
3311 a[1] = Tcl_NewListObj(0,NULL);
3313 b[0] = Tcl_NewStringObj (ltable,1024);
3314 b[1] = Tcl_NewStringObj ("source_tag", -1);
3315 Tcl_IncrRefCount (b[0]);
3316 Tcl_IncrRefCount (b[1]);
3317 line = b[0]->bytes + 1;
3318 strcpy(b[0]->bytes,"\t");
3321 while (fgets (line, 980, fp))
3325 if (ltable[ln >> 3] & (1 << (ln % 8)))
3327 sprintf (buf,"%s insert end {-\t%d} break_tag", widget, ln);
3328 a[0]->length = strlen (buf);
3332 sprintf (buf,"%s insert end { \t%d} \"\"", widget, ln);
3333 a[0]->length = strlen (buf);
3338 if (ltable[ln >> 3] & (1 << (ln % 8)))
3340 sprintf (buf,"%s insert end {-\t} break_tag", widget);
3341 a[0]->length = strlen (buf);
3345 sprintf (buf,"%s insert end { \t} \"\"", widget);
3346 a[0]->length = strlen (buf);
3349 b[0]->length = strlen(b[0]->bytes);
3350 Tcl_SetListObj(a[1],2,b);
3351 cmd = Tcl_ConcatObj(2,a);
3352 Tcl_EvalObj (interp, cmd);
3353 Tcl_DecrRefCount (cmd);
3356 Tcl_DecrRefCount (b[0]);
3357 Tcl_DecrRefCount (b[0]);
3358 Tcl_DecrRefCount (b[1]);
3359 Tcl_DecrRefCount (b[1]);
3365 /* at some point make these static in breakpoint.c and move GUI code there */
3366 extern struct breakpoint *set_raw_breakpoint (struct symtab_and_line sal);
3367 extern void set_breakpoint_count (int);
3368 extern int breakpoint_count;
3370 /* set a breakpoint by source file and line number */
3371 /* flags are as follows: */
3372 /* least significant 2 bits are disposition, rest is */
3373 /* type (normally 0).
3376 bp_breakpoint, Normal breakpoint
3377 bp_hardware_breakpoint, Hardware assisted breakpoint
3380 Disposition of breakpoint. Ie: what to do after hitting it.
3383 del_at_next_stop, Delete at next stop, whether hit or not
3385 donttouch Leave it alone
3390 gdb_set_bp (clientData, interp, objc, objv)
3391 ClientData clientData;
3394 Tcl_Obj *CONST objv[];
3397 struct symtab_and_line sal;
3398 int line, flags, ret;
3399 struct breakpoint *b;
3401 Tcl_Obj *a[5], *cmd;
3405 Tcl_WrongNumArgs(interp, 1, objv, "filename line type");
3409 sal.symtab = full_lookup_symtab (Tcl_GetStringFromObj( objv[1], NULL));
3410 if (sal.symtab == NULL)
3413 if (Tcl_GetIntFromObj( interp, objv[2], &line) == TCL_ERROR)
3416 if (Tcl_GetIntFromObj( interp, objv[3], &flags) == TCL_ERROR)
3420 sal.pc = find_line_pc (sal.symtab, sal.line);
3424 sal.section = find_pc_overlay (sal.pc);
3425 b = set_raw_breakpoint (sal);
3426 set_breakpoint_count (breakpoint_count + 1);
3427 b->number = breakpoint_count;
3428 b->type = flags >> 2;
3429 b->disposition = flags & 3;
3431 /* FIXME: this won't work for duplicate basenames! */
3432 sprintf (buf, "%s:%d", basename(Tcl_GetStringFromObj( objv[1], NULL)), line);
3433 b->addr_string = strsave (buf);
3435 /* now send notification command back to GUI */
3436 sprintf (buf, "0x%x", sal.pc);
3437 a[0] = Tcl_NewStringObj ("gdbtk_tcl_breakpoint create", -1);
3438 a[1] = Tcl_NewIntObj (b->number);
3439 a[2] = Tcl_NewStringObj (buf, -1);
3441 a[4] = Tcl_NewListObj (1,&objv[1]);
3442 cmd = Tcl_ConcatObj(5,a);
3443 ret = Tcl_EvalObj (interp, cmd);
3444 Tcl_DecrRefCount (cmd);
3448 /* Come here during initialize_all_files () */
3451 _initialize_gdbtk ()
3455 /* Tell the rest of the world that Gdbtk is now set up. */
3457 init_ui_hook = gdbtk_init;