1 /* Tcl/Tk interface routines.
2 Copyright 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
4 Written by Stu Grossman <grossman@cygnus.com> of Cygnus Support.
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"
44 /* start-sanitize-ide */
48 /* end-sanitize-ide */
51 #ifdef ANSI_PROTOTYPES
61 #include <sys/ioctl.h>
62 #include "gdb_string.h"
69 #include <sys/stropts.h>
78 #define GDBTK_PATH_SEP ";"
80 #define GDBTK_PATH_SEP ":"
83 /* Some versions (1.3.79, 1.3.81) of Linux don't support SIOCSPGRP the way
84 gdbtk wants to use it... */
89 static int load_in_progress
= 0;
91 int gdbtk_load_hash
PARAMS ((char *, unsigned long));
92 int (*ui_load_progress_hook
) PARAMS ((char *, unsigned long));
93 void (*pre_add_symbol_hook
) PARAMS ((char *));
94 void (*post_add_symbol_hook
) 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 char *gdbtk_readline
PARAMS ((char *));
101 static void gdbtk_init
PARAMS ((char *));
102 static void tk_command_loop
PARAMS ((void));
103 static void gdbtk_call_command
PARAMS ((struct cmd_list_element
*, char *, int));
104 static int gdbtk_wait
PARAMS ((int, struct target_waitstatus
*));
105 static void x_event
PARAMS ((int));
106 static void gdbtk_interactive
PARAMS ((void));
107 static void cleanup_init
PARAMS ((int));
108 static void tk_command
PARAMS ((char *, int));
109 static int gdb_disassemble
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
110 static int compare_lines
PARAMS ((const PTR
, const PTR
));
111 static int gdbtk_dis_asm_read_memory
PARAMS ((bfd_vma
, bfd_byte
*, int, disassemble_info
*));
112 static int gdb_path_conv
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
113 static int gdb_stop
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
114 static int gdb_confirm_quit
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
115 static int gdb_force_quit
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
116 static int gdb_listfiles
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
117 static int gdb_listfuncs
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
118 static int call_wrapper
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
119 static int gdb_cmd
PARAMS ((ClientData
, Tcl_Interp
*, int, char *argv
[]));
120 static int gdb_immediate_command
PARAMS ((ClientData
, Tcl_Interp
*, int, char *argv
[]));
121 static int gdb_fetch_registers
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
122 static void gdbtk_readline_end
PARAMS ((void));
123 static int gdb_changed_register_list
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
124 static void register_changed_p
PARAMS ((int, void *));
125 static int gdb_get_breakpoint_list
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
126 static int gdb_get_breakpoint_info
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
127 static void breakpoint_notify
PARAMS ((struct breakpoint
*, const char *));
128 static void gdbtk_create_breakpoint
PARAMS ((struct breakpoint
*));
129 static void gdbtk_delete_breakpoint
PARAMS ((struct breakpoint
*));
130 static void gdbtk_modify_breakpoint
PARAMS ((struct breakpoint
*));
131 static int gdb_loc
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
132 static int gdb_eval
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
133 static int gdb_sourcelines
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
134 static int map_arg_registers
PARAMS ((int, char *[], void (*) (int, void *), void *));
135 static void get_register_name
PARAMS ((int, void *));
136 static int gdb_regnames
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
137 static void get_register
PARAMS ((int, void *));
138 static int gdb_target_has_execution_command
PARAMS ((ClientData
, Tcl_Interp
*, int, char *argv
[]));
139 static int gdb_load_info
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
140 void TclDebug
PARAMS ((const char *fmt
, ...));
141 static int gdb_get_vars_command
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
142 static int gdb_get_function_command
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
143 static int gdb_get_line_command
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
144 static int gdb_get_file_command
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
145 static int gdb_tracepoint_exists_command
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
146 static int gdb_get_tracepoint_info
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
147 static int gdb_actions_command
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
148 static int gdb_prompt_command
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
149 static int gdb_find_file_command
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
150 static char *find_file_in_dir
PARAMS ((char *));
151 static int gdb_get_tracepoint_list
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
152 static void gdbtk_create_tracepoint
PARAMS ((struct tracepoint
*));
153 static void gdbtk_delete_tracepoint
PARAMS ((struct tracepoint
*));
154 static void tracepoint_notify
PARAMS ((struct tracepoint
*, const char *));
155 void gdbtk_pre_add_symbol
PARAMS ((char *));
156 void gdbtk_post_add_symbol
PARAMS ((void));
158 /* Handle for TCL interpreter */
160 static Tcl_Interp
*interp
= NULL
;
163 static int x_fd
; /* X network socket */
168 /* On Windows we use timer interrupts when gdb might otherwise hang
169 for a long time. See the comment above gdbtk_start_timer. This
170 variable is true when timer interrupts are being used. */
172 static int gdbtk_timer_going
= 0;
174 static void gdbtk_start_timer
PARAMS ((void));
175 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
)
298 Tcl_DStringAppend (result_ptr
, (char *) ptr
, -1);
299 else if (error_string_ptr
!= NULL
&& stream
== gdb_stderr
)
300 Tcl_DStringAppend (error_string_ptr
, (char *) ptr
, -1);
305 Tcl_DStringInit (&str
);
307 Tcl_DStringAppend (&str
, "gdbtk_tcl_fputs", -1);
308 Tcl_DStringAppendElement (&str
, (char *)ptr
);
310 Tcl_Eval (interp
, Tcl_DStringValue (&str
));
311 Tcl_DStringFree (&str
);
316 gdbtk_query (query
, args
)
320 char buf
[200], *merge
[2];
324 vsprintf (buf
, query
, args
);
325 merge
[0] = "gdbtk_tcl_query";
327 command
= Tcl_Merge (2, merge
);
328 Tcl_Eval (interp
, command
);
331 val
= atol (interp
->result
);
337 #ifdef ANSI_PROTOTYPES
338 gdbtk_readline_begin (char *format
, ...)
340 gdbtk_readline_begin (va_alist
)
345 char buf
[200], *merge
[2];
348 #ifdef ANSI_PROTOTYPES
349 va_start (args
, format
);
353 format
= va_arg (args
, char *);
356 vsprintf (buf
, format
, args
);
357 merge
[0] = "gdbtk_tcl_readline_begin";
359 command
= Tcl_Merge (2, merge
);
360 Tcl_Eval (interp
, command
);
365 gdbtk_readline (prompt
)
376 merge
[0] = "gdbtk_tcl_readline";
378 command
= Tcl_Merge (2, merge
);
379 result
= Tcl_Eval (interp
, command
);
381 if (result
== TCL_OK
)
383 return (strdup (interp
-> result
));
387 gdbtk_fputs (interp
-> result
, gdb_stdout
);
388 gdbtk_fputs ("\n", gdb_stdout
);
394 gdbtk_readline_end ()
396 Tcl_Eval (interp
, "gdbtk_tcl_readline_end");
401 #ifdef ANSI_PROTOTYPES
402 dsprintf_append_element (Tcl_DString
*dsp
, char *format
, ...)
404 dsprintf_append_element (va_alist
)
411 #ifdef ANSI_PROTOTYPES
412 va_start (args
, format
);
418 dsp
= va_arg (args
, Tcl_DString
*);
419 format
= va_arg (args
, char *);
422 vsprintf (buf
, format
, args
);
424 Tcl_DStringAppendElement (dsp
, buf
);
428 gdb_path_conv (clientData
, interp
, argc
, argv
)
429 ClientData clientData
;
435 char pathname
[256], *ptr
;
437 error ("wrong # args");
438 cygwin32_conv_to_full_win32_path (argv
[1], pathname
);
439 for (ptr
= pathname
; *ptr
; ptr
++)
445 char *pathname
= argv
[1];
447 Tcl_DStringAppend (result_ptr
, pathname
, strlen(pathname
));
452 gdb_get_breakpoint_list (clientData
, interp
, argc
, argv
)
453 ClientData clientData
;
458 struct breakpoint
*b
;
459 extern struct breakpoint
*breakpoint_chain
;
462 error ("wrong # args");
464 for (b
= breakpoint_chain
; b
; b
= b
->next
)
465 if (b
->type
== bp_breakpoint
)
466 dsprintf_append_element (result_ptr
, "%d", b
->number
);
472 gdb_get_breakpoint_info (clientData
, interp
, argc
, argv
)
473 ClientData clientData
;
478 struct symtab_and_line sal
;
479 static char *bptypes
[] = {"breakpoint", "hardware breakpoint", "until",
480 "finish", "watchpoint", "hardware watchpoint",
481 "read watchpoint", "access watchpoint",
482 "longjmp", "longjmp resume", "step resume",
483 "through sigtramp", "watchpoint scope",
485 static char *bpdisp
[] = {"delete", "delstop", "disable", "donttouch"};
486 struct command_line
*cmd
;
488 struct breakpoint
*b
;
489 extern struct breakpoint
*breakpoint_chain
;
490 char *funcname
, *filename
;
493 error ("wrong # args");
495 bpnum
= atoi (argv
[1]);
497 for (b
= breakpoint_chain
; b
; b
= b
->next
)
498 if (b
->number
== bpnum
)
501 if (!b
|| b
->type
!= bp_breakpoint
)
502 error ("Breakpoint #%d does not exist", bpnum
);
504 sal
= find_pc_line (b
->address
, 0);
506 filename
= symtab_to_filename (sal
.symtab
);
507 if (filename
== NULL
)
509 Tcl_DStringAppendElement (result_ptr
, filename
);
510 find_pc_partial_function (b
->address
, &funcname
, NULL
, NULL
);
511 Tcl_DStringAppendElement (result_ptr
, funcname
);
512 dsprintf_append_element (result_ptr
, "%d", sal
.line
);
513 dsprintf_append_element (result_ptr
, "0x%lx", b
->address
);
514 Tcl_DStringAppendElement (result_ptr
, bptypes
[b
->type
]);
515 Tcl_DStringAppendElement (result_ptr
, b
->enable
== enabled
? "1" : "0");
516 Tcl_DStringAppendElement (result_ptr
, bpdisp
[b
->disposition
]);
517 dsprintf_append_element (result_ptr
, "%d", b
->ignore_count
);
519 Tcl_DStringStartSublist (result_ptr
);
520 for (cmd
= b
->commands
; cmd
; cmd
= cmd
->next
)
521 Tcl_DStringAppendElement (result_ptr
, cmd
->line
);
522 Tcl_DStringEndSublist (result_ptr
);
524 Tcl_DStringAppendElement (result_ptr
, b
->cond_string
);
526 dsprintf_append_element (result_ptr
, "%d", b
->thread
);
527 dsprintf_append_element (result_ptr
, "%d", b
->hit_count
);
533 breakpoint_notify(b
, action
)
534 struct breakpoint
*b
;
539 struct symtab_and_line sal
;
542 if (b
->type
!= bp_breakpoint
)
545 /* We ensure that ACTION contains no special Tcl characters, so we
547 sal
= find_pc_line (b
->address
, 0);
548 filename
= symtab_to_filename (sal
.symtab
);
549 if (filename
== NULL
)
551 sprintf (buf
, "gdbtk_tcl_breakpoint %s %d 0x%lx %d {%s}", action
, b
->number
,
552 (long)b
->address
, sal
.line
, filename
);
554 v
= Tcl_Eval (interp
, buf
);
558 gdbtk_fputs (interp
->result
, gdb_stdout
);
559 gdbtk_fputs ("\n", gdb_stdout
);
564 gdbtk_create_breakpoint(b
)
565 struct breakpoint
*b
;
567 breakpoint_notify (b
, "create");
571 gdbtk_delete_breakpoint(b
)
572 struct breakpoint
*b
;
574 breakpoint_notify (b
, "delete");
578 gdbtk_modify_breakpoint(b
)
579 struct breakpoint
*b
;
581 breakpoint_notify (b
, "modify");
584 /* This implements the TCL command `gdb_loc', which returns a list consisting
585 of the source and line number associated with the current pc. */
588 gdb_loc (clientData
, interp
, argc
, argv
)
589 ClientData clientData
;
595 struct symtab_and_line sal
;
599 if (!have_full_symbols () && !have_partial_symbols ())
601 Tcl_SetResult (interp
, "No symbol table is loaded", TCL_STATIC
);
609 sal
= find_pc_line (selected_frame
->pc
,
610 selected_frame
->next
!= NULL
611 && !selected_frame
->next
->signal_handler_caller
612 && !frame_in_dummy (selected_frame
->next
));
615 sal
= find_pc_line (stop_pc
, 0);
619 struct symtabs_and_lines sals
;
622 sals
= decode_line_spec (argv
[1], 1);
629 error ("Ambiguous line spec");
632 error ("wrong # args");
636 Tcl_DStringAppendElement (result_ptr
, sal
.symtab
->filename
);
638 Tcl_DStringAppendElement (result_ptr
, "");
640 find_pc_partial_function (pc
, &funcname
, NULL
, NULL
);
641 Tcl_DStringAppendElement (result_ptr
, funcname
);
643 filename
= symtab_to_filename (sal
.symtab
);
644 if (filename
== NULL
)
647 Tcl_DStringAppendElement (result_ptr
, filename
);
648 dsprintf_append_element (result_ptr
, "%d", sal
.line
); /* line number */
649 dsprintf_append_element (result_ptr
, "0x%s", paddr_nz(pc
)); /* PC in current frame */
650 dsprintf_append_element (result_ptr
, "0x%s", paddr_nz(stop_pc
)); /* Real PC */
654 /* This implements the TCL command `gdb_eval'. */
657 gdb_eval (clientData
, interp
, argc
, argv
)
658 ClientData clientData
;
663 struct expression
*expr
;
664 struct cleanup
*old_chain
;
668 error ("wrong # args");
670 expr
= parse_expression (argv
[1]);
672 old_chain
= make_cleanup (free_current_contents
, &expr
);
674 val
= evaluate_expression (expr
);
676 val_print (VALUE_TYPE (val
), VALUE_CONTENTS (val
), VALUE_ADDRESS (val
),
677 gdb_stdout
, 0, 0, 0, 0);
679 do_cleanups (old_chain
);
684 /* gdb_get_mem addr form size num aschar*/
685 /* dump a block of memory */
686 /* addr: address of data to dump */
687 /* form: a char indicating format */
688 /* size: size of each element; 1,2,4, or 8 bytes*/
689 /* num: the number of 'size' elements to return */
690 /* acshar: an optional ascii character to use in ASCII dump */
691 /* returns a list of 'num' elements followed by an optional */
694 gdb_get_mem (clientData
, interp
, argc
, argv
)
695 ClientData clientData
;
700 int size
, asize
, num
, i
, j
;
701 CORE_ADDR addr
, saved_addr
, ptr
;
703 struct type
*val_type
;
705 char c
, buff
[128], aschar
;
708 error ("wrong # args");
710 addr
= (CORE_ADDR
)strtoul(argv
[1],(char **)NULL
,0);
713 size
= (int)strtoul(argv
[3],(char **)NULL
,0);
714 num
= (int)strtoul(argv
[4],(char **)NULL
,0);
719 val_type
= builtin_type_char
;
723 val_type
= builtin_type_short
;
727 val_type
= builtin_type_int
;
731 val_type
= builtin_type_long_long
;
735 val_type
= builtin_type_char
;
739 for (i
=0; i
< num
; i
++)
741 vptr
= value_at (val_type
, addr
, (asection
*)NULL
);
742 print_scalar_formatted (VALUE_CONTENTS(vptr
), val_type
, format
, asize
, gdb_stdout
);
743 fputs_unfiltered (" ", gdb_stdout
);
749 val_type
= builtin_type_char
;
753 for (j
=0; j
< num
*size
; j
++)
755 c
= *(char *)VALUE_CONTENTS(value_at (val_type
, ptr
, (asection
*)NULL
));
756 if (c
< 32 || c
> 126)
765 fputs_unfiltered (buff
, gdb_stdout
);
772 /* This implements the TCL command `gdb_sourcelines', which returns a list of
773 all of the lines containing executable code for the specified source file
774 (ie: lines where you can put breakpoints). */
777 gdb_sourcelines (clientData
, interp
, argc
, argv
)
778 ClientData clientData
;
783 struct symtab
*symtab
;
784 struct linetable_entry
*le
;
788 error ("wrong # args");
790 symtab
= lookup_symtab (argv
[1]);
793 error ("No such file");
795 /* If there's no linetable, or no entries, then we are done. */
797 if (!symtab
->linetable
798 || symtab
->linetable
->nitems
== 0)
800 Tcl_DStringAppendElement (result_ptr
, "");
804 le
= symtab
->linetable
->item
;
805 nlines
= symtab
->linetable
->nitems
;
807 for (;nlines
> 0; nlines
--, le
++)
809 /* If the pc of this line is the same as the pc of the next line, then
812 && le
->pc
== (le
+ 1)->pc
)
815 dsprintf_append_element (result_ptr
, "%d", le
->line
);
822 map_arg_registers (argc
, argv
, func
, argp
)
825 void (*func
) PARAMS ((int regnum
, void *argp
));
830 /* Note that the test for a valid register must include checking the
831 reg_names array because NUM_REGS may be allocated for the union of the
832 register sets within a family of related processors. In this case, the
833 trailing entries of reg_names will change depending upon the particular
834 processor being debugged. */
836 if (argc
== 0) /* No args, just do all the regs */
840 && reg_names
[regnum
] != NULL
841 && *reg_names
[regnum
] != '\000';
848 /* Else, list of register #s, just do listed regs */
849 for (; argc
> 0; argc
--, argv
++)
851 regnum
= atoi (*argv
);
855 && reg_names
[regnum
] != NULL
856 && *reg_names
[regnum
] != '\000')
859 error ("bad register number");
866 get_register_name (regnum
, argp
)
868 void *argp
; /* Ignored */
870 Tcl_DStringAppendElement (result_ptr
, reg_names
[regnum
]);
873 /* This implements the TCL command `gdb_regnames', which returns a list of
874 all of the register names. */
877 gdb_regnames (clientData
, interp
, argc
, argv
)
878 ClientData clientData
;
886 return map_arg_registers (argc
, argv
, get_register_name
, NULL
);
889 #ifndef REGISTER_CONVERTIBLE
890 #define REGISTER_CONVERTIBLE(x) (0 != 0)
893 #ifndef REGISTER_CONVERT_TO_VIRTUAL
894 #define REGISTER_CONVERT_TO_VIRTUAL(x, y, z, a)
897 #ifndef INVALID_FLOAT
898 #define INVALID_FLOAT(x, y) (0 != 0)
902 get_register (regnum
, fp
)
906 char raw_buffer
[MAX_REGISTER_RAW_SIZE
];
907 char virtual_buffer
[MAX_REGISTER_VIRTUAL_SIZE
];
908 int format
= (int)fp
;
910 if (read_relative_register_raw_bytes (regnum
, raw_buffer
))
912 Tcl_DStringAppendElement (result_ptr
, "Optimized out");
916 /* Convert raw data to virtual format if necessary. */
918 if (REGISTER_CONVERTIBLE (regnum
))
920 REGISTER_CONVERT_TO_VIRTUAL (regnum
, REGISTER_VIRTUAL_TYPE (regnum
),
921 raw_buffer
, virtual_buffer
);
924 memcpy (virtual_buffer
, raw_buffer
, REGISTER_VIRTUAL_SIZE (regnum
));
929 printf_filtered ("0x");
930 for (j
= 0; j
< REGISTER_RAW_SIZE (regnum
); j
++)
932 register int idx
= TARGET_BYTE_ORDER
== BIG_ENDIAN
? j
933 : REGISTER_RAW_SIZE (regnum
) - 1 - j
;
934 printf_filtered ("%02x", (unsigned char)raw_buffer
[idx
]);
938 val_print (REGISTER_VIRTUAL_TYPE (regnum
), virtual_buffer
, 0,
939 gdb_stdout
, format
, 1, 0, Val_pretty_default
);
941 Tcl_DStringAppend (result_ptr
, " ", -1);
945 gdb_fetch_registers (clientData
, interp
, argc
, argv
)
946 ClientData clientData
;
954 error ("wrong # args");
962 return map_arg_registers (argc
, argv
, get_register
, (void *) format
);
965 /* This contains the previous values of the registers, since the last call to
966 gdb_changed_register_list. */
968 static char old_regs
[REGISTER_BYTES
];
971 register_changed_p (regnum
, argp
)
973 void *argp
; /* Ignored */
975 char raw_buffer
[MAX_REGISTER_RAW_SIZE
];
977 if (read_relative_register_raw_bytes (regnum
, raw_buffer
))
980 if (memcmp (&old_regs
[REGISTER_BYTE (regnum
)], raw_buffer
,
981 REGISTER_RAW_SIZE (regnum
)) == 0)
984 /* Found a changed register. Save new value and return its number. */
986 memcpy (&old_regs
[REGISTER_BYTE (regnum
)], raw_buffer
,
987 REGISTER_RAW_SIZE (regnum
));
989 dsprintf_append_element (result_ptr
, "%d", regnum
);
993 gdb_changed_register_list (clientData
, interp
, argc
, argv
)
994 ClientData clientData
;
1002 return map_arg_registers (argc
, argv
, register_changed_p
, NULL
);
1005 /* This implements the tcl command "gdb_immediate", which does exactly
1006 the same thing as gdb_cmd, except NONE of its outut is buffered. */
1008 gdb_immediate_command (clientData
, interp
, argc
, argv
)
1009 ClientData clientData
;
1014 Tcl_DString
*save_ptr
= NULL
;
1017 error ("wrong # args");
1022 Tcl_DStringAppend (result_ptr
, "", -1);
1023 save_ptr
= result_ptr
;
1026 execute_command (argv
[1], 1);
1028 bpstat_do_actions (&stop_bpstat
);
1030 result_ptr
= save_ptr
;
1035 /* This implements the TCL command `gdb_cmd', which sends its argument into
1036 the GDB command scanner. */
1039 gdb_cmd (clientData
, interp
, argc
, argv
)
1040 ClientData clientData
;
1045 Tcl_DString
*save_ptr
= NULL
;
1048 error ("wrong # args");
1053 /* for the load instruction (and possibly others later) we
1054 set result_ptr to NULL so gdbtk_fputs() will not buffer
1055 all the data until the command is finished. */
1057 if (strncmp ("load ", argv
[1], 5) == 0
1058 || strncmp ("while ", argv
[1], 6) == 0)
1060 Tcl_DStringAppend (result_ptr
, "", -1);
1061 save_ptr
= result_ptr
;
1063 load_in_progress
= 1;
1065 /* On Windows, use timer interrupts so that the user can cancel
1066 the download. FIXME: We may have to do something on other
1069 gdbtk_start_timer ();
1073 execute_command (argv
[1], 1);
1076 if (load_in_progress
)
1077 gdbtk_stop_timer ();
1080 load_in_progress
= 0;
1081 bpstat_do_actions (&stop_bpstat
);
1084 result_ptr
= save_ptr
;
1089 /* Client of call_wrapper - this routine performs the actual call to
1090 the client function. */
1092 struct wrapped_call_args
1103 struct wrapped_call_args
*args
;
1105 args
->val
= (*args
->func
) (args
->func
, args
->interp
, args
->argc
, args
->argv
);
1109 /* This routine acts as a top-level for all GDB code called by tcl/Tk. It
1110 handles cleanups, and calls to return_to_top_level (usually via error).
1111 This is necessary in order to prevent a longjmp out of the bowels of Tk,
1112 possibly leaving things in a bad state. Since this routine can be called
1113 recursively, it needs to save and restore the contents of the jmp_buf as
1117 call_wrapper (clientData
, interp
, argc
, argv
)
1118 ClientData clientData
;
1123 struct wrapped_call_args wrapped_args
;
1124 Tcl_DString result
, *old_result_ptr
;
1125 Tcl_DString error_string
, *old_error_string_ptr
;
1127 Tcl_DStringInit (&result
);
1128 old_result_ptr
= result_ptr
;
1129 result_ptr
= &result
;
1131 Tcl_DStringInit (&error_string
);
1132 old_error_string_ptr
= error_string_ptr
;
1133 error_string_ptr
= &error_string
;
1135 wrapped_args
.func
= (Tcl_CmdProc
*)clientData
;
1136 wrapped_args
.interp
= interp
;
1137 wrapped_args
.argc
= argc
;
1138 wrapped_args
.argv
= argv
;
1139 wrapped_args
.val
= 0;
1141 if (!catch_errors (wrapped_call
, &wrapped_args
, "", RETURN_MASK_ALL
))
1143 wrapped_args
.val
= TCL_ERROR
; /* Flag an error for TCL */
1146 /* Make sure the timer interrupts are turned off. */
1147 if (gdbtk_timer_going
)
1148 gdbtk_stop_timer ();
1151 gdb_flush (gdb_stderr
); /* Flush error output */
1152 gdb_flush (gdb_stdout
); /* Sometimes error output comes here as well */
1154 /* In case of an error, we may need to force the GUI into idle
1155 mode because gdbtk_call_command may have bombed out while in
1156 the command routine. */
1159 Tcl_Eval (interp
, "gdbtk_tcl_idle");
1162 /* if the download was cancelled, don't print the error */
1163 if (load_in_progress
)
1165 Tcl_DStringInit (&error_string
);
1166 wrapped_args
.val
= TCL_OK
;
1167 load_in_progress
= 0;
1170 if (Tcl_DStringLength (&error_string
) == 0)
1172 Tcl_DStringResult (interp
, &result
);
1173 Tcl_DStringFree (&error_string
);
1175 else if (Tcl_DStringLength (&result
) == 0)
1177 Tcl_DStringResult (interp
, &error_string
);
1178 Tcl_DStringFree (&result
);
1179 Tcl_DStringFree (&error_string
);
1183 Tcl_ResetResult (interp
);
1184 Tcl_AppendResult (interp
, Tcl_DStringValue (&result
),
1185 Tcl_DStringValue (&error_string
), (char *) NULL
);
1186 Tcl_DStringFree (&result
);
1187 Tcl_DStringFree (&error_string
);
1190 result_ptr
= old_result_ptr
;
1191 error_string_ptr
= old_error_string_ptr
;
1197 return wrapped_args
.val
;
1201 comp_files (file1
, file2
)
1202 const char *file1
[], *file2
[];
1204 return strcmp(*file1
,*file2
);
1209 gdb_listfiles (clientData
, interp
, objc
, objv
)
1210 ClientData clientData
;
1213 Tcl_Obj
*CONST objv
[];
1215 struct objfile
*objfile
;
1216 struct partial_symtab
*psymtab
;
1217 struct symtab
*symtab
;
1218 char *lastfile
, *pathname
, *files
[1000];
1219 int i
, numfiles
= 0, len
= 0;
1224 Tcl_WrongNumArgs (interp
, 1, objv
, "Usage: gdb_listfiles ?pathname?");
1228 pathname
= Tcl_GetStringFromObj (objv
[1], &len
);
1230 mylist
= Tcl_NewListObj (0, NULL
);
1232 ALL_PSYMTABS (objfile
, psymtab
)
1236 if (psymtab
->filename
)
1237 files
[numfiles
++] = basename(psymtab
->filename
);
1239 else if (!strcmp(psymtab
->filename
,basename(psymtab
->filename
))
1240 || !strncmp(pathname
,psymtab
->filename
,len
))
1241 if (psymtab
->filename
)
1242 files
[numfiles
++] = basename(psymtab
->filename
);
1245 ALL_SYMTABS (objfile
, symtab
)
1249 if (symtab
->filename
)
1250 files
[numfiles
++] = basename(symtab
->filename
);
1252 else if (!strcmp(symtab
->filename
,basename(symtab
->filename
))
1253 || !strncmp(pathname
,symtab
->filename
,len
))
1254 if (symtab
->filename
)
1255 files
[numfiles
++] = basename(symtab
->filename
);
1258 qsort (files
, numfiles
, sizeof(char *), comp_files
);
1261 for (i
= 0; i
< numfiles
; i
++)
1263 if (strcmp(files
[i
],lastfile
))
1264 Tcl_ListObjAppendElement (interp
, mylist
, Tcl_NewStringObj(files
[i
], -1));
1265 lastfile
= files
[i
];
1267 Tcl_SetObjResult (interp
, mylist
);
1272 gdb_listfuncs (clientData
, interp
, argc
, argv
)
1273 ClientData clientData
;
1278 struct symtab
*symtab
;
1279 struct blockvector
*bv
;
1285 error ("wrong # args");
1287 symtab
= lookup_symtab (argv
[1]);
1290 error ("No such file");
1292 bv
= BLOCKVECTOR (symtab
);
1293 for (i
= GLOBAL_BLOCK
; i
<= STATIC_BLOCK
; i
++)
1295 b
= BLOCKVECTOR_BLOCK (bv
, i
);
1296 /* Skip the sort if this block is always sorted. */
1297 if (!BLOCK_SHOULD_SORT (b
))
1298 sort_block_syms (b
);
1299 for (j
= 0; j
< BLOCK_NSYMS (b
); j
++)
1301 sym
= BLOCK_SYM (b
, j
);
1302 if (SYMBOL_CLASS (sym
) == LOC_BLOCK
)
1304 Tcl_DStringAppendElement (result_ptr
, SYMBOL_NAME(sym
));
1312 gdb_stop (clientData
, interp
, argc
, argv
)
1313 ClientData clientData
;
1321 quit_flag
= 1; /* hope something sees this */
1326 /* Prepare to accept a new executable file. This is called when we
1327 want to clear away everything we know about the old file, without
1328 asking the user. The Tcl code will have already asked the user if
1329 necessary. After this is called, we should be able to run the
1330 `file' command without getting any questions. */
1333 gdb_clear_file (clientData
, interp
, argc
, argv
)
1334 ClientData clientData
;
1339 if (inferior_pid
!= 0 && target_has_execution
)
1342 target_detach (NULL
, 0);
1347 if (target_has_execution
)
1350 symbol_file_command (NULL
, 0);
1352 /* gdb_loc refers to stop_pc, but nothing seems to clear it, so we
1353 clear it here. FIXME: This seems like an abstraction violation
1360 /* Ask the user to confirm an exit request. */
1363 gdb_confirm_quit (clientData
, interp
, argc
, argv
)
1364 ClientData clientData
;
1371 ret
= quit_confirm ();
1372 Tcl_DStringAppendElement (result_ptr
, ret
? "1" : "0");
1376 /* Quit without asking for confirmation. */
1379 gdb_force_quit (clientData
, interp
, argc
, argv
)
1380 ClientData clientData
;
1385 quit_force ((char *) NULL
, 1);
1389 /* This implements the TCL command `gdb_disassemble'. */
1392 gdbtk_dis_asm_read_memory (memaddr
, myaddr
, len
, info
)
1396 disassemble_info
*info
;
1398 extern struct target_ops exec_ops
;
1402 res
= xfer_memory (memaddr
, myaddr
, len
, 0, &exec_ops
);
1413 /* We need a different sort of line table from the normal one cuz we can't
1414 depend upon implicit line-end pc's for lines. This is because of the
1415 reordering we are about to do. */
1417 struct my_line_entry
{
1424 compare_lines (mle1p
, mle2p
)
1428 struct my_line_entry
*mle1
, *mle2
;
1431 mle1
= (struct my_line_entry
*) mle1p
;
1432 mle2
= (struct my_line_entry
*) mle2p
;
1434 val
= mle1
->line
- mle2
->line
;
1439 return mle1
->start_pc
- mle2
->start_pc
;
1443 gdb_disassemble (clientData
, interp
, argc
, argv
)
1444 ClientData clientData
;
1449 CORE_ADDR pc
, low
, high
;
1450 int mixed_source_and_assembly
;
1451 static disassemble_info di
;
1452 static int di_initialized
;
1454 if (! di_initialized
)
1456 INIT_DISASSEMBLE_INFO_NO_ARCH (di
, gdb_stdout
,
1457 (fprintf_ftype
) fprintf_unfiltered
);
1458 di
.flavour
= bfd_target_unknown_flavour
;
1459 di
.memory_error_func
= dis_asm_memory_error
;
1460 di
.print_address_func
= dis_asm_print_address
;
1464 di
.mach
= tm_print_insn_info
.mach
;
1465 if (TARGET_BYTE_ORDER
== BIG_ENDIAN
)
1466 di
.endian
= BFD_ENDIAN_BIG
;
1468 di
.endian
= BFD_ENDIAN_LITTLE
;
1470 if (argc
!= 3 && argc
!= 4)
1471 error ("wrong # args");
1473 if (strcmp (argv
[1], "source") == 0)
1474 mixed_source_and_assembly
= 1;
1475 else if (strcmp (argv
[1], "nosource") == 0)
1476 mixed_source_and_assembly
= 0;
1478 error ("First arg must be 'source' or 'nosource'");
1480 low
= parse_and_eval_address (argv
[2]);
1484 if (find_pc_partial_function (low
, NULL
, &low
, &high
) == 0)
1485 error ("No function contains specified address");
1488 high
= parse_and_eval_address (argv
[3]);
1490 /* If disassemble_from_exec == -1, then we use the following heuristic to
1491 determine whether or not to do disassembly from target memory or from the
1494 If we're debugging a local process, read target memory, instead of the
1495 exec file. This makes disassembly of functions in shared libs work
1498 Else, we're debugging a remote process, and should disassemble from the
1499 exec file for speed. However, this is no good if the target modifies its
1500 code (for relocation, or whatever).
1503 if (disassemble_from_exec
== -1)
1504 if (strcmp (target_shortname
, "child") == 0
1505 || strcmp (target_shortname
, "procfs") == 0
1506 || strcmp (target_shortname
, "vxprocess") == 0)
1507 disassemble_from_exec
= 0; /* It's a child process, read inferior mem */
1509 disassemble_from_exec
= 1; /* It's remote, read the exec file */
1511 if (disassemble_from_exec
)
1512 di
.read_memory_func
= gdbtk_dis_asm_read_memory
;
1514 di
.read_memory_func
= dis_asm_read_memory
;
1516 /* If just doing straight assembly, all we need to do is disassemble
1517 everything between low and high. If doing mixed source/assembly, we've
1518 got a totally different path to follow. */
1520 if (mixed_source_and_assembly
)
1521 { /* Come here for mixed source/assembly */
1522 /* The idea here is to present a source-O-centric view of a function to
1523 the user. This means that things are presented in source order, with
1524 (possibly) out of order assembly immediately following. */
1525 struct symtab
*symtab
;
1526 struct linetable_entry
*le
;
1529 struct my_line_entry
*mle
;
1530 struct symtab_and_line sal
;
1535 symtab
= find_pc_symtab (low
); /* Assume symtab is valid for whole PC range */
1540 /* First, convert the linetable to a bunch of my_line_entry's. */
1542 le
= symtab
->linetable
->item
;
1543 nlines
= symtab
->linetable
->nitems
;
1548 mle
= (struct my_line_entry
*) alloca (nlines
* sizeof (struct my_line_entry
));
1552 /* Copy linetable entries for this function into our data structure, creating
1553 end_pc's and setting out_of_order as appropriate. */
1555 /* First, skip all the preceding functions. */
1557 for (i
= 0; i
< nlines
- 1 && le
[i
].pc
< low
; i
++) ;
1559 /* Now, copy all entries before the end of this function. */
1562 for (; i
< nlines
- 1 && le
[i
].pc
< high
; i
++)
1564 if (le
[i
].line
== le
[i
+ 1].line
1565 && le
[i
].pc
== le
[i
+ 1].pc
)
1566 continue; /* Ignore duplicates */
1568 mle
[newlines
].line
= le
[i
].line
;
1569 if (le
[i
].line
> le
[i
+ 1].line
)
1571 mle
[newlines
].start_pc
= le
[i
].pc
;
1572 mle
[newlines
].end_pc
= le
[i
+ 1].pc
;
1576 /* If we're on the last line, and it's part of the function, then we need to
1577 get the end pc in a special way. */
1582 mle
[newlines
].line
= le
[i
].line
;
1583 mle
[newlines
].start_pc
= le
[i
].pc
;
1584 sal
= find_pc_line (le
[i
].pc
, 0);
1585 mle
[newlines
].end_pc
= sal
.end
;
1589 /* Now, sort mle by line #s (and, then by addresses within lines). */
1592 qsort (mle
, newlines
, sizeof (struct my_line_entry
), compare_lines
);
1594 /* Now, for each line entry, emit the specified lines (unless they have been
1595 emitted before), followed by the assembly code for that line. */
1597 next_line
= 0; /* Force out first line */
1598 for (i
= 0; i
< newlines
; i
++)
1600 /* Print out everything from next_line to the current line. */
1602 if (mle
[i
].line
>= next_line
)
1605 print_source_lines (symtab
, next_line
, mle
[i
].line
+ 1, 0);
1607 print_source_lines (symtab
, mle
[i
].line
, mle
[i
].line
+ 1, 0);
1609 next_line
= mle
[i
].line
+ 1;
1612 for (pc
= mle
[i
].start_pc
; pc
< mle
[i
].end_pc
; )
1615 fputs_unfiltered (" ", gdb_stdout
);
1616 print_address (pc
, gdb_stdout
);
1617 fputs_unfiltered (":\t ", gdb_stdout
);
1618 pc
+= (*tm_print_insn
) (pc
, &di
);
1619 fputs_unfiltered ("\n", gdb_stdout
);
1626 for (pc
= low
; pc
< high
; )
1629 fputs_unfiltered (" ", gdb_stdout
);
1630 print_address (pc
, gdb_stdout
);
1631 fputs_unfiltered (":\t ", gdb_stdout
);
1632 pc
+= (*tm_print_insn
) (pc
, &di
);
1633 fputs_unfiltered ("\n", gdb_stdout
);
1637 gdb_flush (gdb_stdout
);
1643 tk_command (cmd
, from_tty
)
1649 struct cleanup
*old_chain
;
1651 /* Catch case of no argument, since this will make the tcl interpreter dump core. */
1653 error_no_arg ("tcl command to interpret");
1655 retval
= Tcl_Eval (interp
, cmd
);
1657 result
= strdup (interp
->result
);
1659 old_chain
= make_cleanup (free
, result
);
1661 if (retval
!= TCL_OK
)
1664 printf_unfiltered ("%s\n", result
);
1666 do_cleanups (old_chain
);
1670 cleanup_init (ignored
)
1674 Tcl_DeleteInterp (interp
);
1678 /* Come here during long calculations to check for GUI events. Usually invoked
1679 via the QUIT macro. */
1682 gdbtk_interactive ()
1684 /* Tk_DoOneEvent (TK_DONT_WAIT|TK_IDLE_EVENTS); */
1687 /* Come here when there is activity on the X file descriptor. */
1693 /* Process pending events */
1695 while (Tcl_DoOneEvent (TCL_DONT_WAIT
|TCL_ALL_EVENTS
) != 0)
1698 /* If we are doing a download, see if the download should be
1699 cancelled. FIXME: We should use a better variable name. */
1700 if (load_in_progress
)
1704 val
= Tcl_GetVar (interp
, "download_cancel_ok", TCL_GLOBAL_ONLY
);
1705 if (val
!= NULL
&& atoi (val
))
1720 /* For Cygwin32, we use a timer to periodically check for Windows
1721 messages. FIXME: It would be better to not poll, but to instead
1722 rewrite the target_wait routines to serve as input sources.
1723 Unfortunately, that will be a lot of work. */
1726 gdbtk_start_timer ()
1728 sigset_t nullsigmask
;
1729 struct sigaction action
;
1730 struct itimerval it
;
1732 sigemptyset (&nullsigmask
);
1734 action
.sa_handler
= x_event
;
1735 action
.sa_mask
= nullsigmask
;
1736 action
.sa_flags
= 0;
1737 sigaction (SIGALRM
, &action
, NULL
);
1739 it
.it_interval
.tv_sec
= 0;
1740 /* Check for messages twice a second. */
1741 it
.it_interval
.tv_usec
= 500 * 1000;
1742 it
.it_value
.tv_sec
= 0;
1743 it
.it_value
.tv_usec
= 500 * 1000;
1745 setitimer (ITIMER_REAL
, &it
, NULL
);
1747 gdbtk_timer_going
= 1;
1753 sigset_t nullsigmask
;
1754 struct sigaction action
;
1755 struct itimerval it
;
1757 gdbtk_timer_going
= 0;
1759 sigemptyset (&nullsigmask
);
1761 action
.sa_handler
= SIG_IGN
;
1762 action
.sa_mask
= nullsigmask
;
1763 action
.sa_flags
= 0;
1764 sigaction (SIGALRM
, &action
, NULL
);
1766 it
.it_interval
.tv_sec
= 0;
1767 it
.it_interval
.tv_usec
= 0;
1768 it
.it_value
.tv_sec
= 0;
1769 it
.it_value
.tv_usec
= 0;
1770 setitimer (ITIMER_REAL
, &it
, NULL
);
1775 /* This hook function is called whenever we want to wait for the
1779 gdbtk_wait (pid
, ourstatus
)
1781 struct target_waitstatus
*ourstatus
;
1784 struct sigaction action
;
1785 static sigset_t nullsigmask
= {0};
1789 /* Needed for SunOS 4.1.x */
1790 #define SA_RESTART 0
1793 action
.sa_handler
= x_event
;
1794 action
.sa_mask
= nullsigmask
;
1795 action
.sa_flags
= SA_RESTART
;
1796 sigaction(SIGIO
, &action
, NULL
);
1800 /* Call x_event ourselves now, as well as starting the timer;
1801 otherwise, if single stepping, we may never wait long enough for
1802 the timer to trigger. */
1805 gdbtk_start_timer ();
1808 pid
= target_wait (pid
, ourstatus
);
1811 gdbtk_stop_timer ();
1815 action
.sa_handler
= SIG_IGN
;
1816 sigaction(SIGIO
, &action
, NULL
);
1822 /* This is called from execute_command, and provides a wrapper around
1823 various command routines in a place where both protocol messages and
1824 user input both flow through. Mostly this is used for indicating whether
1825 the target process is running or not.
1829 gdbtk_call_command (cmdblk
, arg
, from_tty
)
1830 struct cmd_list_element
*cmdblk
;
1835 if (cmdblk
->class == class_run
|| cmdblk
->class == class_trace
)
1838 Tcl_Eval (interp
, "gdbtk_tcl_busy");
1839 (*cmdblk
->function
.cfunc
)(arg
, from_tty
);
1841 Tcl_Eval (interp
, "gdbtk_tcl_idle");
1844 (*cmdblk
->function
.cfunc
)(arg
, from_tty
);
1847 /* This function is called instead of gdb's internal command loop. This is the
1848 last chance to do anything before entering the main Tk event loop. */
1853 extern GDB_FILE
*instream
;
1855 /* We no longer want to use stdin as the command input stream */
1858 if (Tcl_Eval (interp
, "gdbtk_tcl_preloop") != TCL_OK
)
1862 /* Force errorInfo to be set up propertly. */
1863 Tcl_AddErrorInfo (interp
, "");
1865 msg
= Tcl_GetVar (interp
, "errorInfo", TCL_GLOBAL_ONLY
);
1867 MessageBox (NULL
, msg
, NULL
, MB_OK
| MB_ICONERROR
| MB_TASKMODAL
);
1869 fputs_unfiltered (msg
, gdb_stderr
);
1880 /* gdbtk_init installs this function as a final cleanup. */
1883 gdbtk_cleanup (dummy
)
1889 /* Initialize gdbtk. */
1892 gdbtk_init ( argv0
)
1895 struct cleanup
*old_chain
;
1896 char *lib
, *gdbtk_lib
, *gdbtk_lib_tmp
, *gdbtk_file
;
1899 struct sigaction action
;
1900 static sigset_t nullsigmask
= {0};
1903 /* start-sanitize-ide */
1904 struct ide_event_handle
*h
;
1907 /* end-sanitize-ide */
1910 /* If there is no DISPLAY environment variable, Tk_Init below will fail,
1911 causing gdb to abort. If instead we simply return here, gdb will
1912 gracefully degrade to using the command line interface. */
1915 if (getenv ("DISPLAY") == NULL
)
1919 old_chain
= make_cleanup (cleanup_init
, 0);
1921 /* First init tcl and tk. */
1922 Tcl_FindExecutable (argv0
);
1923 interp
= Tcl_CreateInterp ();
1926 error ("Tcl_CreateInterp failed");
1928 if (Tcl_Init(interp
) != TCL_OK
)
1929 error ("Tcl_Init failed: %s", interp
->result
);
1931 make_final_cleanup (gdbtk_cleanup
, NULL
);
1933 /* Initialize the Paths variable. */
1934 if (ide_initialize_paths (interp
, "gdbtcl") != TCL_OK
)
1935 error ("ide_initialize_paths failed: %s", interp
->result
);
1938 /* start-sanitize-ide */
1939 /* Find the directory where we expect to find idemanager. We ignore
1940 errors since it doesn't really matter if this fails. */
1941 libexecdir
= Tcl_GetVar2 (interp
, "Paths", "libexecdir", TCL_GLOBAL_ONLY
);
1945 h
= ide_event_init_from_environment (&errmsg
, libexecdir
);
1948 Tcl_AppendResult (interp
, "can't initialize event system: ", errmsg
,
1950 fprintf(stderr
, "WARNING: ide_event_init_client failed: %s\n", interp
->result
);
1952 Tcl_SetVar (interp
, "GDBTK_IDE", "0", 0);
1956 if (ide_create_tclevent_command (interp
, h
) != TCL_OK
)
1957 error ("ide_create_tclevent_command failed: %s", interp
->result
);
1959 if (ide_create_edit_command (interp
, h
) != TCL_OK
)
1960 error ("ide_create_edit_command failed: %s", interp
->result
);
1962 if (ide_create_property_command (interp
, h
) != TCL_OK
)
1963 error ("ide_create_property_command failed: %s", interp
->result
);
1965 if (ide_create_build_command (interp
, h
) != TCL_OK
)
1966 error ("ide_create_build_command failed: %s", interp
->result
);
1968 if (ide_create_window_register_command (interp
, h
, "gdb-restore")
1970 error ("ide_create_window_register_command failed: %s",
1973 if (ide_create_window_command (interp
, h
) != TCL_OK
)
1974 error ("ide_create_window_command failed: %s", interp
->result
);
1976 if (ide_create_exit_command (interp
, h
) != TCL_OK
)
1977 error ("ide_create_exit_command failed: %s", interp
->result
);
1979 if (ide_create_help_command (interp
) != TCL_OK
)
1980 error ("ide_create_help_command failed: %s", interp
->result
);
1983 if (ide_initialize (interp, "gdb") != TCL_OK)
1984 error ("ide_initialize failed: %s", interp->result);
1987 Tcl_SetVar (interp
, "GDBTK_IDE", "1", 0);
1988 Tcl_SetVar (interp
, "IDE", "1", TCL_GLOBAL_ONLY
);
1990 /* end-sanitize-ide */
1992 Tcl_SetVar (interp
, "GDBTK_IDE", "0", 0);
1995 /* We don't want to open the X connection until we've done all the
1996 IDE initialization. Otherwise, goofy looking unfinished windows
1997 pop up when ILU drops into the TCL event loop. */
1999 if (Tk_Init(interp
) != TCL_OK
)
2000 error ("Tk_Init failed: %s", interp
->result
);
2002 if (Itcl_Init(interp
) == TCL_ERROR
)
2003 error ("Itcl_Init failed: %s", interp
->result
);
2005 if (Tix_Init(interp
) != TCL_OK
)
2006 error ("Tix_Init failed: %s", interp
->result
);
2009 /* On Windows, create a sizebox widget command */
2010 if (ide_create_sizebox_command (interp
) != TCL_OK
)
2011 error ("sizebox creation failed");
2012 if (ide_create_winprint_command (interp
) != TCL_OK
)
2013 error ("windows print code initialization failed");
2014 /* start-sanitize-ide */
2015 /* An interface to ShellExecute. */
2016 if (ide_create_shell_execute_command (interp
) != TCL_OK
)
2017 error ("shell execute command initialization failed");
2018 /* end-sanitize-ide */
2021 Tcl_CreateCommand (interp
, "gdb_cmd", call_wrapper
, gdb_cmd
, NULL
);
2022 Tcl_CreateCommand (interp
, "gdb_immediate", call_wrapper
,
2023 gdb_immediate_command
, NULL
);
2024 Tcl_CreateCommand (interp
, "gdb_loc", call_wrapper
, gdb_loc
, NULL
);
2025 Tcl_CreateCommand (interp
, "gdb_path_conv", call_wrapper
, gdb_path_conv
, NULL
);
2026 Tcl_CreateCommand (interp
, "gdb_sourcelines", call_wrapper
, gdb_sourcelines
,
2028 Tcl_CreateObjCommand (interp
, "gdb_listfiles", gdb_listfiles
, NULL
, NULL
);
2029 Tcl_CreateCommand (interp
, "gdb_listfuncs", call_wrapper
, gdb_listfuncs
,
2031 Tcl_CreateCommand (interp
, "gdb_get_mem", call_wrapper
, gdb_get_mem
,
2033 Tcl_CreateCommand (interp
, "gdb_stop", call_wrapper
, gdb_stop
, NULL
);
2034 Tcl_CreateCommand (interp
, "gdb_regnames", call_wrapper
, gdb_regnames
, NULL
);
2035 Tcl_CreateCommand (interp
, "gdb_fetch_registers", call_wrapper
,
2036 gdb_fetch_registers
, NULL
);
2037 Tcl_CreateCommand (interp
, "gdb_changed_register_list", call_wrapper
,
2038 gdb_changed_register_list
, NULL
);
2039 Tcl_CreateCommand (interp
, "gdb_disassemble", call_wrapper
,
2040 gdb_disassemble
, NULL
);
2041 Tcl_CreateCommand (interp
, "gdb_eval", call_wrapper
, gdb_eval
, NULL
);
2042 Tcl_CreateCommand (interp
, "gdb_get_breakpoint_list", call_wrapper
,
2043 gdb_get_breakpoint_list
, NULL
);
2044 Tcl_CreateCommand (interp
, "gdb_get_breakpoint_info", call_wrapper
,
2045 gdb_get_breakpoint_info
, NULL
);
2046 Tcl_CreateCommand (interp
, "gdb_clear_file", call_wrapper
,
2047 gdb_clear_file
, NULL
);
2048 Tcl_CreateCommand (interp
, "gdb_confirm_quit", call_wrapper
,
2049 gdb_confirm_quit
, NULL
);
2050 Tcl_CreateCommand (interp
, "gdb_force_quit", call_wrapper
,
2051 gdb_force_quit
, NULL
);
2052 Tcl_CreateCommand (interp
, "gdb_target_has_execution",
2053 gdb_target_has_execution_command
,
2055 Tcl_CreateObjCommand (interp
, "gdb_load_info", gdb_load_info
, NULL
, NULL
);
2056 Tcl_CreateObjCommand (interp
, "gdb_get_locals", gdb_get_vars_command
,
2057 (ClientData
) 0, NULL
);
2058 Tcl_CreateObjCommand (interp
, "gdb_get_args", gdb_get_vars_command
,
2059 (ClientData
) 1, NULL
);
2060 Tcl_CreateObjCommand (interp
, "gdb_get_function", gdb_get_function_command
,
2062 Tcl_CreateObjCommand (interp
, "gdb_get_line", gdb_get_line_command
,
2064 Tcl_CreateObjCommand (interp
, "gdb_get_file", gdb_get_file_command
,
2066 Tcl_CreateObjCommand (interp
, "gdb_tracepoint_exists",
2067 gdb_tracepoint_exists_command
, NULL
, NULL
);
2068 Tcl_CreateObjCommand (interp
, "gdb_get_tracepoint_info",
2069 gdb_get_tracepoint_info
, NULL
, NULL
);
2070 Tcl_CreateObjCommand (interp
, "gdb_actions",
2071 gdb_actions_command
, NULL
, NULL
);
2072 Tcl_CreateObjCommand (interp
, "gdb_prompt",
2073 gdb_prompt_command
, NULL
, NULL
);
2074 Tcl_CreateObjCommand (interp
, "gdb_find_file",
2075 gdb_find_file_command
, NULL
, NULL
);
2076 Tcl_CreateObjCommand (interp
, "gdb_get_tracepoint_list",
2077 gdb_get_tracepoint_list
, NULL
, NULL
);
2079 command_loop_hook
= tk_command_loop
;
2080 print_frame_info_listing_hook
=
2081 (void (*) PARAMS ((struct symtab
*, int, int, int))) null_routine
;
2082 query_hook
= gdbtk_query
;
2083 flush_hook
= gdbtk_flush
;
2084 create_breakpoint_hook
= gdbtk_create_breakpoint
;
2085 delete_breakpoint_hook
= gdbtk_delete_breakpoint
;
2086 modify_breakpoint_hook
= gdbtk_modify_breakpoint
;
2087 interactive_hook
= gdbtk_interactive
;
2088 target_wait_hook
= gdbtk_wait
;
2089 call_command_hook
= gdbtk_call_command
;
2090 readline_begin_hook
= gdbtk_readline_begin
;
2091 readline_hook
= gdbtk_readline
;
2092 readline_end_hook
= gdbtk_readline_end
;
2093 ui_load_progress_hook
= gdbtk_load_hash
;
2094 pre_add_symbol_hook
= gdbtk_pre_add_symbol
;
2095 post_add_symbol_hook
= gdbtk_post_add_symbol
;
2096 create_tracepoint_hook
= gdbtk_create_tracepoint
;
2097 delete_tracepoint_hook
= gdbtk_delete_tracepoint
;
2100 /* Get the file descriptor for the X server */
2102 x_fd
= ConnectionNumber (Tk_Display (Tk_MainWindow (interp
)));
2104 /* Setup for I/O interrupts */
2106 action
.sa_mask
= nullsigmask
;
2107 action
.sa_flags
= 0;
2108 action
.sa_handler
= SIG_IGN
;
2109 sigaction(SIGIO
, &action
, NULL
);
2113 if (ioctl (x_fd
, FIOASYNC
, &i
))
2114 perror_with_name ("gdbtk_init: ioctl FIOASYNC failed");
2118 if (ioctl (x_fd
, SIOCSPGRP
, &i
))
2119 perror_with_name ("gdbtk_init: ioctl SIOCSPGRP failed");
2124 if (fcntl (x_fd
, F_SETOWN
, i
))
2125 perror_with_name ("gdbtk_init: fcntl F_SETOWN failed");
2126 #endif /* F_SETOWN */
2127 #endif /* !SIOCSPGRP */
2130 if (ioctl (x_fd
, I_SETSIG
, S_INPUT
|S_RDNORM
) < 0)
2131 perror_with_name ("gdbtk_init: ioctl I_SETSIG failed");
2134 #endif /* ifndef FIOASYNC */
2137 add_com ("tk", class_obscure
, tk_command
,
2138 "Send a command directly into tk.");
2140 Tcl_LinkVar (interp
, "disassemble-from-exec", (char *)&disassemble_from_exec
,
2143 /* find the gdb tcl library and source main.tcl */
2145 gdbtk_lib
= getenv ("GDBTK_LIBRARY");
2147 if (access ("gdbtcl/main.tcl", R_OK
) == 0)
2148 gdbtk_lib
= "gdbtcl";
2150 gdbtk_lib
= GDBTK_LIBRARY
;
2152 gdbtk_lib_tmp
= xstrdup (gdbtk_lib
);
2155 /* see if GDBTK_LIBRARY is a path list */
2156 lib
= strtok (gdbtk_lib_tmp
, GDBTK_PATH_SEP
);
2159 if (Tcl_VarEval (interp
, "lappend auto_path ", lib
, NULL
) != TCL_OK
)
2161 fputs_unfiltered (Tcl_GetVar (interp
, "errorInfo", 0), gdb_stderr
);
2166 gdbtk_file
= concat (lib
, "/main.tcl", (char *) NULL
);
2167 if (access (gdbtk_file
, R_OK
) == 0)
2170 Tcl_SetVar (interp
, "GDBTK_LIBRARY", lib
, 0);
2174 while ((lib
= strtok (NULL
, ":")) != NULL
);
2176 free (gdbtk_lib_tmp
);
2180 /* Try finding it with the auto path. */
2182 static const char script
[] ="\
2183 proc gdbtk_find_main {} {\n\
2184 global auto_path GDBTK_LIBRARY\n\
2185 foreach dir $auto_path {\n\
2186 set f [file join $dir main.tcl]\n\
2187 if {[file exists $f]} then {\n\
2188 set GDBTK_LIBRARY $dir\n\
2196 if (Tcl_GlobalEval (interp
, (char *) script
) != TCL_OK
)
2198 fputs_unfiltered (Tcl_GetVar (interp
, "errorInfo", 0), gdb_stderr
);
2202 if (interp
->result
[0] != '\0')
2204 gdbtk_file
= xstrdup (interp
->result
);
2211 fputs_unfiltered_hook
= NULL
; /* Force errors to stdout/stderr */
2212 if (getenv("GDBTK_LIBRARY"))
2214 fprintf_unfiltered (stderr
, "Unable to find main.tcl in %s\n",getenv("GDBTK_LIBRARY"));
2215 fprintf_unfiltered (stderr
,
2216 "Please set GDBTK_LIBRARY to a path that includes the GDB tcl files.\n");
2220 fprintf_unfiltered (stderr
, "Unable to find main.tcl in %s\n", GDBTK_LIBRARY
);
2221 fprintf_unfiltered (stderr
, "You might want to set GDBTK_LIBRARY\n");
2226 /* Defer setup of fputs_unfiltered_hook to near the end so that error messages
2227 prior to this point go to stdout/stderr. */
2229 fputs_unfiltered_hook
= gdbtk_fputs
;
2231 if (Tcl_EvalFile (interp
, gdbtk_file
) != TCL_OK
)
2235 /* Force errorInfo to be set up propertly. */
2236 Tcl_AddErrorInfo (interp
, "");
2238 msg
= Tcl_GetVar (interp
, "errorInfo", TCL_GLOBAL_ONLY
);
2240 fputs_unfiltered_hook
= NULL
; /* Force errors to stdout/stderr */
2243 MessageBox (NULL
, msg
, NULL
, MB_OK
| MB_ICONERROR
| MB_TASKMODAL
);
2245 fputs_unfiltered (msg
, gdb_stderr
);
2252 /* start-sanitize-ide */
2253 /* Don't do this until we have initialized. Otherwise, we may get a
2254 run command before we are ready for one. */
2255 if (ide_run_server_init (interp
, h
) != TCL_OK
)
2256 error ("ide_run_server_init failed: %s", interp
->result
);
2257 /* end-sanitize-ide */
2262 discard_cleanups (old_chain
);
2266 gdb_target_has_execution_command (clientData
, interp
, argc
, argv
)
2267 ClientData clientData
;
2274 if (target_has_execution
&& inferior_pid
!= 0)
2277 Tcl_SetIntObj (Tcl_GetObjResult (interp
), result
);
2281 /* gdb_load_info - returns information about the file about to be downloaded */
2284 gdb_load_info (clientData
, interp
, objc
, objv
)
2285 ClientData clientData
;
2288 Tcl_Obj
*CONST objv
[];
2291 struct cleanup
*old_cleanups
;
2297 char *filename
= Tcl_GetStringFromObj (objv
[1], NULL
);
2299 loadfile_bfd
= bfd_openr (filename
, gnutarget
);
2300 if (loadfile_bfd
== NULL
)
2302 Tcl_SetObjResult (interp
, Tcl_NewStringObj ("Open failed", -1));
2305 old_cleanups
= make_cleanup (bfd_close
, loadfile_bfd
);
2307 if (!bfd_check_format (loadfile_bfd
, bfd_object
))
2309 Tcl_SetObjResult (interp
, Tcl_NewStringObj ("Bad Object File", -1));
2313 for (s
= loadfile_bfd
->sections
; s
; s
= s
->next
)
2315 if (s
->flags
& SEC_LOAD
)
2317 bfd_size_type size
= bfd_get_section_size_before_reloc (s
);
2320 ob
[0] = Tcl_NewStringObj((char *)bfd_get_section_name(loadfile_bfd
, s
), -1);
2321 ob
[1] = Tcl_NewLongObj ((long)size
);
2322 res
[i
++] = Tcl_NewListObj (2, ob
);
2327 Tcl_SetObjResult (interp
, Tcl_NewListObj (i
, res
));
2328 do_cleanups (old_cleanups
);
2334 gdbtk_load_hash (section
, num
)
2339 sprintf (buf
, "download_hash %s %ld", section
, num
);
2340 Tcl_Eval (interp
, buf
);
2341 return atoi (interp
->result
);
2344 /* gdb_get_vars_command -
2346 * Implements the "gdb_get_locals" and "gdb_get_args" tcl commands. This
2347 * function sets the Tcl interpreter's result to a list of variable names
2348 * depending on clientData. If clientData is one, the result is a list of
2349 * arguments; zero returns a list of locals -- all relative to the block
2350 * specified as an argument to the command. Valid commands include
2351 * anything decode_line_1 can handle (like "main.c:2", "*0x02020202",
2355 gdb_get_vars_command (clientData
, interp
, objc
, objv
)
2356 ClientData clientData
;
2359 Tcl_Obj
*CONST objv
[];
2362 struct symtabs_and_lines sals
;
2364 struct block
*block
;
2365 char **canonical
, *args
;
2366 int i
, nsyms
, arguments
;
2370 Tcl_AppendResult (interp
,
2371 "wrong # of args: should be \"",
2372 Tcl_GetStringFromObj (objv
[0], NULL
),
2373 " function:line|function|line|*addr\"");
2377 arguments
= (int) clientData
;
2378 args
= Tcl_GetStringFromObj (objv
[1], NULL
);
2379 sals
= decode_line_1 (&args
, 1, NULL
, 0, &canonical
);
2380 if (sals
.nelts
== 0)
2382 Tcl_AppendResult (interp
,
2383 "error decoding line", NULL
);
2387 /* Initialize a list that will hold the results */
2388 result
= Tcl_NewListObj (0, NULL
);
2390 /* Resolve all line numbers to PC's */
2391 for (i
= 0; i
< sals
.nelts
; i
++)
2392 resolve_sal_pc (&sals
.sals
[i
]);
2394 block
= block_for_pc (sals
.sals
[0].pc
);
2397 nsyms
= BLOCK_NSYMS (block
);
2398 for (i
= 0; i
< nsyms
; i
++)
2400 sym
= BLOCK_SYM (block
, i
);
2401 switch (SYMBOL_CLASS (sym
)) {
2403 case LOC_UNDEF
: /* catches errors */
2404 case LOC_CONST
: /* constant */
2405 case LOC_STATIC
: /* static */
2406 case LOC_REGISTER
: /* register */
2407 case LOC_TYPEDEF
: /* local typedef */
2408 case LOC_LABEL
: /* local label */
2409 case LOC_BLOCK
: /* local function */
2410 case LOC_CONST_BYTES
: /* loc. byte seq. */
2411 case LOC_UNRESOLVED
: /* unresolved static */
2412 case LOC_OPTIMIZED_OUT
: /* optimized out */
2414 case LOC_ARG
: /* argument */
2415 case LOC_REF_ARG
: /* reference arg */
2416 case LOC_REGPARM
: /* register arg */
2417 case LOC_REGPARM_ADDR
: /* indirect register arg */
2418 case LOC_LOCAL_ARG
: /* stack arg */
2419 case LOC_BASEREG_ARG
: /* basereg arg */
2421 Tcl_ListObjAppendElement (interp
, result
,
2422 Tcl_NewStringObj (SYMBOL_NAME (sym
), -1));
2424 case LOC_LOCAL
: /* stack local */
2425 case LOC_BASEREG
: /* basereg local */
2427 Tcl_ListObjAppendElement (interp
, result
,
2428 Tcl_NewStringObj (SYMBOL_NAME (sym
), -1));
2432 if (BLOCK_FUNCTION (block
))
2435 block
= BLOCK_SUPERBLOCK (block
);
2438 Tcl_SetObjResult (interp
, result
);
2443 gdb_get_line_command (clientData
, interp
, objc
, objv
)
2444 ClientData clientData
;
2447 Tcl_Obj
*CONST objv
[];
2450 struct symtabs_and_lines sals
;
2451 char *args
, **canonical
;
2455 Tcl_AppendResult (interp
, "wrong # of args: should be \"",
2456 Tcl_GetStringFromObj (objv
[0], NULL
),
2461 args
= Tcl_GetStringFromObj (objv
[1], NULL
);
2462 sals
= decode_line_1 (&args
, 1, NULL
, 0, &canonical
);
2463 if (sals
.nelts
== 1)
2465 Tcl_SetObjResult (interp
, Tcl_NewIntObj (sals
.sals
[0].line
));
2469 Tcl_SetResult (interp
, "N/A", TCL_STATIC
);
2474 gdb_get_file_command (clientData
, interp
, objc
, objv
)
2475 ClientData clientData
;
2478 Tcl_Obj
*CONST objv
[];
2481 struct symtabs_and_lines sals
;
2482 char *args
, **canonical
;
2486 Tcl_AppendResult (interp
, "wrong # of args: should be \"",
2487 Tcl_GetStringFromObj (objv
[0], NULL
),
2492 args
= Tcl_GetStringFromObj (objv
[1], NULL
);
2493 sals
= decode_line_1 (&args
, 1, NULL
, 0, &canonical
);
2494 if (sals
.nelts
== 1)
2496 Tcl_SetResult (interp
, sals
.sals
[0].symtab
->filename
, TCL_VOLATILE
);
2500 Tcl_SetResult (interp
, "N/A", TCL_STATIC
);
2505 gdb_get_function_command (clientData
, interp
, objc
, objv
)
2506 ClientData clientData
;
2509 Tcl_Obj
*CONST objv
[];
2513 struct symtabs_and_lines sals
;
2514 char *args
, **canonical
;
2518 Tcl_AppendResult (interp
, "wrong # of args: should be \"",
2519 Tcl_GetStringFromObj (objv
[0], NULL
),
2524 args
= Tcl_GetStringFromObj (objv
[1], NULL
);
2525 sals
= decode_line_1 (&args
, 1, NULL
, 0, &canonical
);
2526 if (sals
.nelts
== 1)
2528 resolve_sal_pc (&sals
.sals
[0]);
2529 find_pc_partial_function (sals
.sals
[0].pc
, &function
, NULL
, NULL
);
2530 if (function
!= NULL
)
2532 Tcl_SetResult (interp
, function
, TCL_VOLATILE
);
2537 Tcl_SetResult (interp
, "N/A", TCL_STATIC
);
2542 gdb_get_tracepoint_info (clientData
, interp
, objc
, objv
)
2543 ClientData clientData
;
2546 Tcl_Obj
*CONST objv
[];
2548 struct symtab_and_line sal
;
2550 struct tracepoint
*tp
;
2551 struct action_line
*al
;
2552 Tcl_Obj
*list
, *action_list
;
2553 char *filename
, *funcname
;
2557 error ("wrong # args");
2559 Tcl_GetIntFromObj (NULL
, objv
[1], &tpnum
);
2561 ALL_TRACEPOINTS (tp
)
2562 if (tp
->number
== tpnum
)
2566 error ("Tracepoint #%d does not exist", tpnum
);
2568 list
= Tcl_NewListObj (0, NULL
);
2569 sal
= find_pc_line (tp
->address
, 0);
2570 filename
= symtab_to_filename (sal
.symtab
);
2571 if (filename
== NULL
)
2573 Tcl_ListObjAppendElement (interp
, list
,
2574 Tcl_NewStringObj (filename
, -1));
2575 find_pc_partial_function (tp
->address
, &funcname
, NULL
, NULL
);
2576 Tcl_ListObjAppendElement (interp
, list
, Tcl_NewStringObj (funcname
, -1));
2577 Tcl_ListObjAppendElement (interp
, list
, Tcl_NewIntObj (sal
.line
));
2578 sprintf (tmp
, "0x%08x", tp
->address
);
2579 Tcl_ListObjAppendElement (interp
, list
, Tcl_NewStringObj (tmp
, -1));
2580 Tcl_ListObjAppendElement (interp
, list
, Tcl_NewIntObj (tp
->enabled
));
2581 Tcl_ListObjAppendElement (interp
, list
, Tcl_NewIntObj (tp
->pass_count
));
2582 Tcl_ListObjAppendElement (interp
, list
, Tcl_NewIntObj (tp
->step_count
));
2583 Tcl_ListObjAppendElement (interp
, list
, Tcl_NewIntObj (tp
->thread
));
2584 Tcl_ListObjAppendElement (interp
, list
, Tcl_NewIntObj (tp
->hit_count
));
2586 /* Append a list of actions */
2587 action_list
= Tcl_NewListObj (0, NULL
);
2588 for (al
= tp
->actions
; al
!= NULL
; al
= al
->next
)
2590 Tcl_ListObjAppendElement (interp
, action_list
,
2591 Tcl_NewStringObj (al
->action
, -1));
2593 Tcl_ListObjAppendElement (interp
, list
, action_list
);
2595 Tcl_SetObjResult (interp
, list
);
2600 gdbtk_create_tracepoint (tp
)
2601 struct tracepoint
*tp
;
2603 tracepoint_notify (tp
, "create");
2607 gdbtk_delete_tracepoint (tp
)
2608 struct tracepoint
*tp
;
2610 tracepoint_notify (tp
, "delete");
2614 tracepoint_notify(tp
, action
)
2615 struct tracepoint
*tp
;
2620 struct symtab_and_line sal
;
2623 /* We ensure that ACTION contains no special Tcl characters, so we
2625 sal
= find_pc_line (tp
->address
, 0);
2627 filename
= symtab_to_filename (sal
.symtab
);
2628 if (filename
== NULL
)
2630 sprintf (buf
, "gdbtk_tcl_tracepoint %s %d 0x%lx %d {%s}", action
, tp
->number
,
2631 (long)tp
->address
, sal
.line
, filename
);
2633 v
= Tcl_Eval (interp
, buf
);
2637 gdbtk_fputs (interp
->result
, gdb_stdout
);
2638 gdbtk_fputs ("\n", gdb_stdout
);
2642 /* returns -1 if not found, tracepoint # if found */
2644 tracepoint_exists (char * args
)
2646 struct tracepoint
*tp
;
2648 struct symtabs_and_lines sals
;
2652 sals
= decode_line_1 (&args
, 1, NULL
, 0, &canonical
);
2653 if (sals
.nelts
== 1)
2655 resolve_sal_pc (&sals
.sals
[0]);
2656 file
= xmalloc (strlen (sals
.sals
[0].symtab
->dirname
)
2657 + strlen (sals
.sals
[0].symtab
->filename
) + 1);
2660 strcpy (file
, sals
.sals
[0].symtab
->dirname
);
2661 strcat (file
, sals
.sals
[0].symtab
->filename
);
2663 ALL_TRACEPOINTS (tp
)
2665 if (tp
->address
== sals
.sals
[0].pc
)
2666 result
= tp
->number
;
2667 else if (tp
->source_file
!= NULL
2668 && strcmp (tp
->source_file
, file
) == 0
2669 && sals
.sals
[0].line
== tp
->line_number
)
2671 result
= tp
->number
;
2681 gdb_actions_command (clientData
, interp
, objc
, objv
)
2682 ClientData clientData
;
2685 Tcl_Obj
*CONST objv
[];
2687 struct tracepoint
*tp
;
2689 int nactions
, i
, len
;
2690 char *number
, *args
, *action
;
2692 struct action_line
*next
= NULL
, *temp
;
2696 Tcl_AppendResult (interp
, "wrong # args: should be: \"",
2697 Tcl_GetStringFromObj (objv
[0], NULL
),
2698 " number actions\"");
2702 args
= number
= Tcl_GetStringFromObj (objv
[1], NULL
);
2703 tp
= get_tracepoint_by_number (&args
);
2706 Tcl_AppendResult (interp
, "Tracepoint \"", number
, "\" does not exist");
2710 /* Free any existing actions */
2711 for (temp
= tp
->actions
; temp
!= NULL
; temp
= next
)
2715 free (temp
->action
);
2720 Tcl_ListObjGetElements (interp
, objv
[2], &nactions
, &actions
);
2721 for (i
= 0; i
< nactions
; i
++)
2723 temp
= xmalloc (sizeof (struct action_line
));
2725 action
= Tcl_GetStringFromObj (actions
[i
], &len
);
2726 temp
->action
= savestring (action
, len
);
2727 if (sscanf (temp
->action
, "while-stepping %d", &step_count
) !=0)
2728 tp
->step_count
= step_count
;
2745 gdb_tracepoint_exists_command (clientData
, interp
, objc
, objv
)
2746 ClientData clientData
;
2749 Tcl_Obj
*CONST objv
[];
2755 Tcl_AppendResult (interp
, "wrong # of args: should be \"",
2756 Tcl_GetStringFromObj (objv
[0], NULL
),
2757 " function:line|function|line|*addr\"");
2761 args
= Tcl_GetStringFromObj (objv
[1], NULL
);
2763 Tcl_SetObjResult (interp
, Tcl_NewIntObj (tracepoint_exists (args
)));
2767 /* Return the prompt to the interpreter */
2769 gdb_prompt_command (clientData
, interp
, objc
, objv
)
2770 ClientData clientData
;
2773 Tcl_Obj
*CONST objv
[];
2775 Tcl_SetResult (interp
, get_prompt (), TCL_VOLATILE
);
2779 /* return a list of all tracepoint numbers in interpreter */
2781 gdb_get_tracepoint_list (clientData
, interp
, objc
, objv
)
2782 ClientData clientData
;
2785 Tcl_Obj
*CONST objv
[];
2788 struct tracepoint
*tp
;
2790 list
= Tcl_NewListObj (0, NULL
);
2792 ALL_TRACEPOINTS (tp
)
2793 Tcl_ListObjAppendElement (interp
, list
, Tcl_NewIntObj (tp
->number
));
2795 Tcl_SetObjResult (interp
, list
);
2799 /* This is stolen from source.c */
2800 #ifdef CRLF_SOURCE_FILES
2802 /* Define CRLF_SOURCE_FILES in an xm-*.h file if source files on the
2803 host use \r\n rather than just \n. Defining CRLF_SOURCE_FILES is
2804 much faster than defining LSEEK_NOT_LINEAR. */
2810 #define OPEN_MODE (O_RDONLY | O_BINARY)
2812 #else /* ! defined (CRLF_SOURCE_FILES) */
2814 #define OPEN_MODE O_RDONLY
2816 #endif /* ! defined (CRLF_SOURCE_FILES) */
2818 /* Find the pathname to a file, searching the source_dir */
2819 /* we may actually need to use openp to find the the full pathname
2820 so we don't have any "../" et al in it. */
2822 gdb_find_file_command (clientData
, interp
, objc
, objv
)
2823 ClientData clientData
;
2826 Tcl_Obj
*CONST objv
[];
2828 char *file
, *filename
;
2832 Tcl_AppendResult (interp
, "wrong # of args: should be \"",
2833 Tcl_GetStringFromObj (objv
[0], NULL
),
2838 file
= Tcl_GetStringFromObj (objv
[1], NULL
);
2839 filename
= find_file_in_dir (file
);
2841 if (filename
== NULL
)
2842 Tcl_SetResult (interp
, "", TCL_STATIC
);
2844 Tcl_SetObjResult (interp
, Tcl_NewStringObj (filename
, -1));
2850 find_file_in_dir (file
)
2853 struct symtab
*st
= NULL
;
2857 /* try something simple first */
2858 if (access (file
, R_OK
) == 0)
2861 /* We really need a symtab for this to work... */
2862 st
= lookup_symtab (file
);
2865 file
= symtab_to_filename (st
);
2874 /* This hook is called whenever we are ready to load a symbol file so that
2875 the UI can notify the user... */
2877 gdbtk_pre_add_symbol (name
)
2882 sprintf (command
, "gdbtk_tcl_pre_add_symbol %s", name
);
2883 Tcl_Eval (interp
, command
);
2886 /* This hook is called whenever we finish loading a symbol file. */
2888 gdbtk_post_add_symbol ()
2890 Tcl_Eval (interp
, "gdbtk_tcl_post_add_symbol");
2894 /* TclDebug (const char *fmt, ...) works just like printf() but */
2895 /* sends the output to the GDB TK debug window. */
2896 /* Not for normal use; just a convenient tool for debugging */
2898 #ifdef ANSI_PROTOTYPES
2899 TclDebug (const char *fmt
, ...)
2908 #ifdef ANSI_PROTOTYPES
2909 va_start (args
, fmt
);
2913 fmt
= va_arg (args
, char *);
2916 strcpy (buf
, "debug \"");
2917 vsprintf (&buf
[7], fmt
, args
);
2920 Tcl_Eval (interp
, buf
);
2924 /* Come here during initialize_all_files () */
2927 _initialize_gdbtk ()
2931 /* Tell the rest of the world that Gdbtk is now set up. */
2933 init_ui_hook
= gdbtk_init
;