1 /* Tcl/Tk interface routines.
2 Copyright 1994, 1995, 1996, 1997, 1998 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"
45 /* start-sanitize-ide */
49 /* end-sanitize-ide */
52 #ifdef ANSI_PROTOTYPES
62 #include <sys/ioctl.h>
63 #include "gdb_string.h"
70 #include <sys/stropts.h>
80 #define GDBTK_PATH_SEP ";"
82 #define GDBTK_PATH_SEP ":"
85 /* Some versions (1.3.79, 1.3.81) of Linux don't support SIOCSPGRP the way
86 gdbtk wants to use it... */
91 static int No_Update
= 0;
92 static int load_in_progress
= 0;
93 static int in_fputs
= 0;
95 int gdbtk_load_hash
PARAMS ((char *, unsigned long));
96 int (*ui_load_progress_hook
) PARAMS ((char *, unsigned long));
97 void (*pre_add_symbol_hook
) PARAMS ((char *));
98 void (*post_add_symbol_hook
) PARAMS ((void));
100 /* This is a disgusting hack. Unfortunately, the UI will lock up if we
101 are doing something like blocking in a system call, waiting for serial I/O,
104 This hook should be used whenever we might block. This means adding appropriate
105 timeouts to code and what not to allow this hook to be called. */
106 void (*ui_loop_hook
) PARAMS ((int));
108 char * get_prompt
PARAMS ((void));
110 static void null_routine
PARAMS ((int));
111 static void gdbtk_flush
PARAMS ((FILE *));
112 static void gdbtk_fputs
PARAMS ((const char *, FILE *));
113 static int gdbtk_query
PARAMS ((const char *, va_list));
114 static char *gdbtk_readline
PARAMS ((char *));
115 static void gdbtk_init
PARAMS ((char *));
116 static void tk_command_loop
PARAMS ((void));
117 static void gdbtk_call_command
PARAMS ((struct cmd_list_element
*, char *, int));
118 static int gdbtk_wait
PARAMS ((int, struct target_waitstatus
*));
119 static void x_event
PARAMS ((int));
120 static void gdbtk_interactive
PARAMS ((void));
121 static void cleanup_init
PARAMS ((int));
122 static void tk_command
PARAMS ((char *, int));
123 static int gdb_disassemble
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
124 static int compare_lines
PARAMS ((const PTR
, const PTR
));
125 static int gdbtk_dis_asm_read_memory
PARAMS ((bfd_vma
, bfd_byte
*, int, disassemble_info
*));
126 static int gdb_path_conv
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
127 static int gdb_stop
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
128 static int gdb_confirm_quit
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
129 static int gdb_force_quit
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
130 static int gdb_listfiles
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
131 static int gdb_listfuncs
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
132 static int call_wrapper
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
133 static int gdb_cmd
PARAMS ((ClientData
, Tcl_Interp
*, int, char *argv
[]));
134 static int gdb_immediate_command
PARAMS ((ClientData
, Tcl_Interp
*, int, char *argv
[]));
135 static int gdb_fetch_registers
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
136 static void gdbtk_readline_end
PARAMS ((void));
137 static void pc_changed
PARAMS ((void));
138 static int gdb_changed_register_list
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
139 static void register_changed_p
PARAMS ((int, void *));
140 static int gdb_get_breakpoint_list
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
141 static int gdb_get_breakpoint_info
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
142 static void breakpoint_notify
PARAMS ((struct breakpoint
*, const char *));
143 static void gdbtk_create_breakpoint
PARAMS ((struct breakpoint
*));
144 static void gdbtk_delete_breakpoint
PARAMS ((struct breakpoint
*));
145 static void gdbtk_modify_breakpoint
PARAMS ((struct breakpoint
*));
146 static int gdb_loc
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
147 static int gdb_eval
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
148 static int map_arg_registers
PARAMS ((int, char *[], void (*) (int, void *), void *));
149 static void get_register_name
PARAMS ((int, void *));
150 static int gdb_regnames
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
151 static void get_register
PARAMS ((int, void *));
152 static int gdb_trace_status
PARAMS ((ClientData
, Tcl_Interp
*, int, char *argv
[]));
153 static int gdb_target_has_execution_command
PARAMS ((ClientData
, Tcl_Interp
*, int, char *argv
[]));
154 static int gdb_load_info
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
155 void TclDebug
PARAMS ((const char *fmt
, ...));
156 static int gdb_get_vars_command
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
157 static int gdb_get_function_command
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
158 static int gdb_get_line_command
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
159 static int gdb_get_file_command
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
160 static int gdb_tracepoint_exists_command
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
161 static int gdb_get_tracepoint_info
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
162 static int gdb_actions_command
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
163 static int gdb_prompt_command
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
164 static int gdb_find_file_command
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
165 static int gdb_get_tracepoint_list
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
166 static void gdbtk_create_tracepoint
PARAMS ((struct tracepoint
*));
167 static void gdbtk_delete_tracepoint
PARAMS ((struct tracepoint
*));
168 static void gdbtk_modify_tracepoint
PARAMS ((struct tracepoint
*));
169 static void tracepoint_notify
PARAMS ((struct tracepoint
*, const char *));
170 static void gdbtk_print_frame_info
PARAMS ((struct symtab
*, int, int, int));
171 void gdbtk_pre_add_symbol
PARAMS ((char *));
172 void gdbtk_post_add_symbol
PARAMS ((void));
173 static int get_pc_register
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
174 static int gdb_loadfile
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
175 static int gdb_set_bp
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
176 static struct symtab
*full_lookup_symtab
PARAMS ((char *file
));
177 static int gdb_get_mem
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
179 static void gdbtk_annotate_starting
PARAMS ((void));
180 static void gdbtk_annotate_stopped
PARAMS ((void));
181 static void gdbtk_annotate_signalled
PARAMS ((void));
182 static void gdbtk_annotate_exited
PARAMS ((void));
185 /* Handle for TCL interpreter */
186 static Tcl_Interp
*interp
= NULL
;
189 static int x_fd
; /* X network socket */
194 /* On Windows we use timer interrupts when gdb might otherwise hang
195 for a long time. See the comment above gdbtk_start_timer. This
196 variable is true when timer interrupts are being used. */
198 static int gdbtk_timer_going
= 0;
200 static void gdbtk_start_timer
PARAMS ((void));
201 static void gdbtk_stop_timer
PARAMS ((void));
205 /* This variable is true when the inferior is running. Although it's
206 possible to disable most input from widgets and thus prevent
207 attempts to do anything while the inferior is running, any commands
208 that get through - even a simple memory read - are Very Bad, and
209 may cause GDB to crash or behave strangely. So, this variable
210 provides an extra layer of defense. */
212 static int running_now
;
214 /* This variable determines where memory used for disassembly is read from.
215 If > 0, then disassembly comes from the exec file rather than the
216 target (which might be at the other end of a slow serial link). If
217 == 0 then disassembly comes from target. If < 0 disassembly is
218 automatically switched to the target if it's an inferior process,
219 otherwise the exec file is used. */
221 static int disassemble_from_exec
= -1;
225 /* Supply malloc calls for tcl/tk. We do not want to do this on
226 Windows, because Tcl_Alloc is probably in a DLL which will not call
227 the mmalloc routines. */
233 return xmalloc (size
);
237 Tcl_Realloc (ptr
, size
)
241 return xrealloc (ptr
, size
);
251 #endif /* ! _WIN32 */
261 /* On Windows, if we hold a file open, other programs can't write to
262 it. In particular, we don't want to hold the executable open,
263 because it will mean that people have to get out of the debugging
264 session in order to remake their program. So we close it, although
265 this will cost us if and when we need to reopen it. */
275 bfd_cache_close (o
->obfd
);
278 if (exec_bfd
!= NULL
)
279 bfd_cache_close (exec_bfd
);
284 /* The following routines deal with stdout/stderr data, which is created by
285 {f}printf_{un}filtered and friends. gdbtk_fputs and gdbtk_flush are the
286 lowest level of these routines and capture all output from the rest of GDB.
287 Normally they present their data to tcl via callbacks to the following tcl
288 routines: gdbtk_tcl_fputs, gdbtk_tcl_fputs_error, and gdbtk_flush. These
289 in turn call tk routines to update the display.
291 Under some circumstances, you may want to collect the output so that it can
292 be returned as the value of a tcl procedure. This can be done by
293 surrounding the output routines with calls to start_saving_output and
294 finish_saving_output. The saved data can then be retrieved with
295 get_saved_output (but this must be done before the call to
296 finish_saving_output). */
298 /* Dynamic string for output. */
300 static Tcl_DString
*result_ptr
;
302 /* Dynamic string for stderr. This is only used if result_ptr is
305 static Tcl_DString
*error_string_ptr
;
312 /* Force immediate screen update */
314 Tcl_VarEval (interp
, "gdbtk_tcl_flush", NULL
);
319 gdbtk_fputs (ptr
, stream
)
323 char *merge
[2], *command
;
327 Tcl_DStringAppend (result_ptr
, (char *) ptr
, -1);
328 else if (error_string_ptr
!= NULL
&& stream
== gdb_stderr
)
329 Tcl_DStringAppend (error_string_ptr
, (char *) ptr
, -1);
332 merge
[0] = "gdbtk_tcl_fputs";
333 merge
[1] = (char *)ptr
;
334 command
= Tcl_Merge (2, merge
);
335 Tcl_Eval (interp
, command
);
342 gdbtk_query (query
, args
)
346 char buf
[200], *merge
[2];
350 vsprintf (buf
, query
, args
);
351 merge
[0] = "gdbtk_tcl_query";
353 command
= Tcl_Merge (2, merge
);
354 Tcl_Eval (interp
, command
);
357 val
= atol (interp
->result
);
363 #ifdef ANSI_PROTOTYPES
364 gdbtk_readline_begin (char *format
, ...)
366 gdbtk_readline_begin (va_alist
)
371 char buf
[200], *merge
[2];
374 #ifdef ANSI_PROTOTYPES
375 va_start (args
, format
);
379 format
= va_arg (args
, char *);
382 vsprintf (buf
, format
, args
);
383 merge
[0] = "gdbtk_tcl_readline_begin";
385 command
= Tcl_Merge (2, merge
);
386 Tcl_Eval (interp
, command
);
391 gdbtk_readline (prompt
)
402 merge
[0] = "gdbtk_tcl_readline";
404 command
= Tcl_Merge (2, merge
);
405 result
= Tcl_Eval (interp
, command
);
407 if (result
== TCL_OK
)
409 return (strdup (interp
-> result
));
413 gdbtk_fputs (interp
-> result
, gdb_stdout
);
414 gdbtk_fputs ("\n", gdb_stdout
);
420 gdbtk_readline_end ()
422 Tcl_Eval (interp
, "gdbtk_tcl_readline_end");
428 Tcl_Eval (interp
, "gdbtk_pc_changed");
433 #ifdef ANSI_PROTOTYPES
434 dsprintf_append_element (Tcl_DString
*dsp
, char *format
, ...)
436 dsprintf_append_element (va_alist
)
443 #ifdef ANSI_PROTOTYPES
444 va_start (args
, format
);
450 dsp
= va_arg (args
, Tcl_DString
*);
451 format
= va_arg (args
, char *);
454 vsprintf (buf
, format
, args
);
456 Tcl_DStringAppendElement (dsp
, buf
);
460 gdb_path_conv (clientData
, interp
, argc
, argv
)
461 ClientData clientData
;
467 char pathname
[256], *ptr
;
469 error ("wrong # args");
470 cygwin32_conv_to_full_win32_path (argv
[1], pathname
);
471 for (ptr
= pathname
; *ptr
; ptr
++)
477 char *pathname
= argv
[1];
479 Tcl_DStringAppend (result_ptr
, pathname
, strlen(pathname
));
484 gdb_get_breakpoint_list (clientData
, interp
, argc
, argv
)
485 ClientData clientData
;
490 struct breakpoint
*b
;
491 extern struct breakpoint
*breakpoint_chain
;
494 error ("wrong # args");
496 for (b
= breakpoint_chain
; b
; b
= b
->next
)
497 if (b
->type
== bp_breakpoint
)
498 dsprintf_append_element (result_ptr
, "%d", b
->number
);
504 gdb_get_breakpoint_info (clientData
, interp
, argc
, argv
)
505 ClientData clientData
;
510 struct symtab_and_line sal
;
511 static char *bptypes
[] = {"breakpoint", "hardware breakpoint", "until",
512 "finish", "watchpoint", "hardware watchpoint",
513 "read watchpoint", "access watchpoint",
514 "longjmp", "longjmp resume", "step resume",
515 "through sigtramp", "watchpoint scope",
517 static char *bpdisp
[] = {"delete", "delstop", "disable", "donttouch"};
518 struct command_line
*cmd
;
520 struct breakpoint
*b
;
521 extern struct breakpoint
*breakpoint_chain
;
522 char *funcname
, *fname
, *filename
;
525 error ("wrong # args");
527 bpnum
= atoi (argv
[1]);
529 for (b
= breakpoint_chain
; b
; b
= b
->next
)
530 if (b
->number
== bpnum
)
533 if (!b
|| b
->type
!= bp_breakpoint
)
534 error ("Breakpoint #%d does not exist", bpnum
);
536 sal
= find_pc_line (b
->address
, 0);
538 filename
= symtab_to_filename (sal
.symtab
);
539 if (filename
== NULL
)
541 Tcl_DStringAppendElement (result_ptr
, filename
);
543 find_pc_partial_function (b
->address
, &funcname
, NULL
, NULL
);
544 fname
= cplus_demangle (funcname
, 0);
547 Tcl_DStringAppendElement (result_ptr
, fname
);
551 Tcl_DStringAppendElement (result_ptr
, funcname
);
552 dsprintf_append_element (result_ptr
, "%d", b
->line_number
);
553 dsprintf_append_element (result_ptr
, "0x%lx", b
->address
);
554 Tcl_DStringAppendElement (result_ptr
, bptypes
[b
->type
]);
555 Tcl_DStringAppendElement (result_ptr
, b
->enable
== enabled
? "1" : "0");
556 Tcl_DStringAppendElement (result_ptr
, bpdisp
[b
->disposition
]);
557 dsprintf_append_element (result_ptr
, "%d", b
->ignore_count
);
559 Tcl_DStringStartSublist (result_ptr
);
560 for (cmd
= b
->commands
; cmd
; cmd
= cmd
->next
)
561 Tcl_DStringAppendElement (result_ptr
, cmd
->line
);
562 Tcl_DStringEndSublist (result_ptr
);
564 Tcl_DStringAppendElement (result_ptr
, b
->cond_string
);
566 dsprintf_append_element (result_ptr
, "%d", b
->thread
);
567 dsprintf_append_element (result_ptr
, "%d", b
->hit_count
);
573 breakpoint_notify(b
, action
)
574 struct breakpoint
*b
;
579 struct symtab_and_line sal
;
582 if (b
->type
!= bp_breakpoint
)
585 /* We ensure that ACTION contains no special Tcl characters, so we
587 sal
= find_pc_line (b
->address
, 0);
588 filename
= symtab_to_filename (sal
.symtab
);
589 if (filename
== NULL
)
592 sprintf (buf
, "gdbtk_tcl_breakpoint %s %d 0x%lx %d {%s}", action
, b
->number
,
593 (long)b
->address
, b
->line_number
, filename
);
595 v
= Tcl_Eval (interp
, buf
);
599 gdbtk_fputs (interp
->result
, gdb_stdout
);
600 gdbtk_fputs ("\n", gdb_stdout
);
605 gdbtk_create_breakpoint(b
)
606 struct breakpoint
*b
;
608 breakpoint_notify (b
, "create");
612 gdbtk_delete_breakpoint(b
)
613 struct breakpoint
*b
;
615 breakpoint_notify (b
, "delete");
619 gdbtk_modify_breakpoint(b
)
620 struct breakpoint
*b
;
622 breakpoint_notify (b
, "modify");
625 /* This implements the TCL command `gdb_loc', which returns a list */
626 /* consisting of the following: */
627 /* basename, function name, filename, line number, address, current pc */
630 gdb_loc (clientData
, interp
, argc
, argv
)
631 ClientData clientData
;
637 struct symtab_and_line sal
;
638 char *funcname
, *fname
;
641 if (!have_full_symbols () && !have_partial_symbols ())
643 Tcl_SetResult (interp
, "No symbol table is loaded", TCL_STATIC
);
649 if (selected_frame
&& (selected_frame
->pc
!= stop_pc
))
651 /* Note - this next line is not correct on all architectures. */
652 /* For a graphical debugged we really want to highlight the */
653 /* assembly line that called the next function on the stack. */
654 /* Many architectures have the next instruction saved as the */
655 /* pc on the stack, so what happens is the next instruction is hughlighted. */
657 pc
= selected_frame
->pc
;
658 sal
= find_pc_line (selected_frame
->pc
,
659 selected_frame
->next
!= NULL
660 && !selected_frame
->next
->signal_handler_caller
661 && !frame_in_dummy (selected_frame
->next
));
666 sal
= find_pc_line (stop_pc
, 0);
671 struct symtabs_and_lines sals
;
674 sals
= decode_line_spec (argv
[1], 1);
681 error ("Ambiguous line spec");
686 error ("wrong # args");
689 Tcl_DStringAppendElement (result_ptr
, sal
.symtab
->filename
);
691 Tcl_DStringAppendElement (result_ptr
, "");
693 find_pc_partial_function (pc
, &funcname
, NULL
, NULL
);
694 fname
= cplus_demangle (funcname
, 0);
697 Tcl_DStringAppendElement (result_ptr
, fname
);
701 Tcl_DStringAppendElement (result_ptr
, funcname
);
702 filename
= symtab_to_filename (sal
.symtab
);
703 if (filename
== NULL
)
706 Tcl_DStringAppendElement (result_ptr
, filename
);
707 dsprintf_append_element (result_ptr
, "%d", sal
.line
); /* line number */
708 dsprintf_append_element (result_ptr
, "0x%s", paddr_nz(pc
)); /* PC in current frame */
709 dsprintf_append_element (result_ptr
, "0x%s", paddr_nz(stop_pc
)); /* Real PC */
713 /* This implements the TCL command `gdb_eval'. */
716 gdb_eval (clientData
, interp
, argc
, argv
)
717 ClientData clientData
;
722 struct expression
*expr
;
723 struct cleanup
*old_chain
;
727 error ("wrong # args");
729 expr
= parse_expression (argv
[1]);
731 old_chain
= make_cleanup (free_current_contents
, &expr
);
733 val
= evaluate_expression (expr
);
735 val_print (VALUE_TYPE (val
), VALUE_CONTENTS (val
), VALUE_ADDRESS (val
),
736 gdb_stdout
, 0, 0, 0, 0);
738 do_cleanups (old_chain
);
743 /* gdb_get_mem addr form size num aschar*/
744 /* dump a block of memory */
745 /* addr: address of data to dump */
746 /* form: a char indicating format */
747 /* size: size of each element; 1,2,4, or 8 bytes*/
748 /* num: the number of bytes to read */
749 /* acshar: an optional ascii character to use in ASCII dump */
750 /* returns a list of elements followed by an optional */
754 gdb_get_mem (clientData
, interp
, argc
, argv
)
755 ClientData clientData
;
760 int size
, asize
, i
, j
, bc
;
762 int nbytes
, rnum
, bpr
;
763 char format
, c
, *ptr
, buff
[128], aschar
, *mbuf
, *mptr
, *cptr
, *bptr
;
764 struct type
*val_type
;
766 if (argc
< 6 || argc
> 7)
768 interp
->result
= "addr format size bytes bytes_per_row ?ascii_char?";
772 size
= (int)strtoul(argv
[3],(char **)NULL
,0);
773 nbytes
= (int)strtoul(argv
[4],(char **)NULL
,0);
774 bpr
= (int)strtoul(argv
[5],(char **)NULL
,0);
775 if (nbytes
<= 0 || bpr
<= 0 || size
<= 0)
777 interp
->result
= "Invalid number of bytes.";
781 addr
= (CORE_ADDR
)strtoul(argv
[1],(char **)NULL
,0);
783 mbuf
= (char *)malloc (nbytes
+32);
786 interp
->result
= "Out of memory.";
789 memset (mbuf
, 0, nbytes
+32);
792 rnum
= target_read_memory_partial (addr
, mbuf
, nbytes
, NULL
);
801 val_type
= builtin_type_char
;
805 val_type
= builtin_type_short
;
809 val_type
= builtin_type_int
;
813 val_type
= builtin_type_long_long
;
817 val_type
= builtin_type_char
;
821 bc
= 0; /* count of bytes in a row */
822 buff
[0] = '"'; /* buffer for ascii dump */
823 bptr
= &buff
[1]; /* pointer for ascii dump */
825 for (i
=0; i
< nbytes
; i
+= size
)
829 fputs_unfiltered ("N/A ", gdb_stdout
);
831 for ( j
= 0; j
< size
; j
++)
836 print_scalar_formatted (mptr
, val_type
, format
, asize
, gdb_stdout
);
837 fputs_unfiltered (" ", gdb_stdout
);
840 for ( j
= 0; j
< size
; j
++)
843 if (c
< 32 || c
> 126)
855 if (aschar
&& (bc
>= bpr
))
857 /* end of row. print it and reset variables */
862 fputs_unfiltered (buff
, gdb_stdout
);
872 map_arg_registers (argc
, argv
, func
, argp
)
875 void (*func
) PARAMS ((int regnum
, void *argp
));
880 /* Note that the test for a valid register must include checking the
881 reg_names array because NUM_REGS may be allocated for the union of the
882 register sets within a family of related processors. In this case, the
883 trailing entries of reg_names will change depending upon the particular
884 processor being debugged. */
886 if (argc
== 0) /* No args, just do all the regs */
890 && reg_names
[regnum
] != NULL
891 && *reg_names
[regnum
] != '\000';
898 /* Else, list of register #s, just do listed regs */
899 for (; argc
> 0; argc
--, argv
++)
901 regnum
= atoi (*argv
);
905 && reg_names
[regnum
] != NULL
906 && *reg_names
[regnum
] != '\000')
909 error ("bad register number");
916 get_register_name (regnum
, argp
)
918 void *argp
; /* Ignored */
920 Tcl_DStringAppendElement (result_ptr
, reg_names
[regnum
]);
923 /* This implements the TCL command `gdb_regnames', which returns a list of
924 all of the register names. */
927 gdb_regnames (clientData
, interp
, argc
, argv
)
928 ClientData clientData
;
936 return map_arg_registers (argc
, argv
, get_register_name
, NULL
);
939 #ifndef REGISTER_CONVERTIBLE
940 #define REGISTER_CONVERTIBLE(x) (0 != 0)
943 #ifndef REGISTER_CONVERT_TO_VIRTUAL
944 #define REGISTER_CONVERT_TO_VIRTUAL(x, y, z, a)
947 #ifndef INVALID_FLOAT
948 #define INVALID_FLOAT(x, y) (0 != 0)
952 get_register (regnum
, fp
)
956 char raw_buffer
[MAX_REGISTER_RAW_SIZE
];
957 char virtual_buffer
[MAX_REGISTER_VIRTUAL_SIZE
];
958 int format
= (int)fp
;
963 if (read_relative_register_raw_bytes (regnum
, raw_buffer
))
965 Tcl_DStringAppendElement (result_ptr
, "Optimized out");
969 /* Convert raw data to virtual format if necessary. */
971 if (REGISTER_CONVERTIBLE (regnum
))
973 REGISTER_CONVERT_TO_VIRTUAL (regnum
, REGISTER_VIRTUAL_TYPE (regnum
),
974 raw_buffer
, virtual_buffer
);
977 memcpy (virtual_buffer
, raw_buffer
, REGISTER_VIRTUAL_SIZE (regnum
));
982 printf_filtered ("0x");
983 for (j
= 0; j
< REGISTER_RAW_SIZE (regnum
); j
++)
985 register int idx
= TARGET_BYTE_ORDER
== BIG_ENDIAN
? j
986 : REGISTER_RAW_SIZE (regnum
) - 1 - j
;
987 printf_filtered ("%02x", (unsigned char)raw_buffer
[idx
]);
991 val_print (REGISTER_VIRTUAL_TYPE (regnum
), virtual_buffer
, 0,
992 gdb_stdout
, format
, 1, 0, Val_pretty_default
);
994 Tcl_DStringAppend (result_ptr
, " ", -1);
998 get_pc_register (clientData
, interp
, argc
, argv
)
999 ClientData clientData
;
1004 sprintf(interp
->result
,"0x%llx",(long long)read_register(PC_REGNUM
));
1009 gdb_fetch_registers (clientData
, interp
, argc
, argv
)
1010 ClientData clientData
;
1018 error ("wrong # args");
1024 return map_arg_registers (argc
, argv
, get_register
, (void *) format
);
1027 /* This contains the previous values of the registers, since the last call to
1028 gdb_changed_register_list. */
1030 static char old_regs
[REGISTER_BYTES
];
1033 register_changed_p (regnum
, argp
)
1035 void *argp
; /* Ignored */
1037 char raw_buffer
[MAX_REGISTER_RAW_SIZE
];
1039 if (read_relative_register_raw_bytes (regnum
, raw_buffer
))
1042 if (memcmp (&old_regs
[REGISTER_BYTE (regnum
)], raw_buffer
,
1043 REGISTER_RAW_SIZE (regnum
)) == 0)
1046 /* Found a changed register. Save new value and return its number. */
1048 memcpy (&old_regs
[REGISTER_BYTE (regnum
)], raw_buffer
,
1049 REGISTER_RAW_SIZE (regnum
));
1051 dsprintf_append_element (result_ptr
, "%d", regnum
);
1055 gdb_changed_register_list (clientData
, interp
, argc
, argv
)
1056 ClientData clientData
;
1064 return map_arg_registers (argc
, argv
, register_changed_p
, NULL
);
1067 /* This implements the tcl command "gdb_immediate", which does exactly
1068 the same thing as gdb_cmd, except NONE of its outut is buffered. */
1069 /* This will also ALWAYS cause the busy,update, and idle hooks to be
1070 called, contrasted with gdb_cmd, which NEVER calls them. */
1072 gdb_immediate_command (clientData
, interp
, argc
, argv
)
1073 ClientData clientData
;
1078 Tcl_DString
*save_ptr
= NULL
;
1081 error ("wrong # args");
1083 if (running_now
|| load_in_progress
)
1088 Tcl_DStringAppend (result_ptr
, "", -1);
1089 save_ptr
= result_ptr
;
1092 execute_command (argv
[1], 1);
1094 bpstat_do_actions (&stop_bpstat
);
1096 result_ptr
= save_ptr
;
1101 /* This implements the TCL command `gdb_cmd', which sends its argument into
1102 the GDB command scanner. */
1103 /* This command will never cause the update, idle and busy hooks to be called
1106 gdb_cmd (clientData
, interp
, argc
, argv
)
1107 ClientData clientData
;
1112 Tcl_DString
*save_ptr
= NULL
;
1115 error ("wrong # args");
1117 if (running_now
|| load_in_progress
)
1122 /* for the load instruction (and possibly others later) we
1123 set result_ptr to NULL so gdbtk_fputs() will not buffer
1124 all the data until the command is finished. */
1126 if (strncmp ("load ", argv
[1], 5) == 0
1127 || strncmp ("while ", argv
[1], 6) == 0)
1129 Tcl_DStringAppend (result_ptr
, "", -1);
1130 save_ptr
= result_ptr
;
1132 load_in_progress
= 1;
1134 /* On Windows, use timer interrupts so that the user can cancel
1135 the download. FIXME: We may have to do something on other
1138 gdbtk_start_timer ();
1142 execute_command (argv
[1], 1);
1145 if (load_in_progress
)
1146 gdbtk_stop_timer ();
1149 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 /* This routine acts as a top-level for all GDB code called by tcl/Tk. It
1179 handles cleanups, and calls to return_to_top_level (usually via error).
1180 This is necessary in order to prevent a longjmp out of the bowels of Tk,
1181 possibly leaving things in a bad state. Since this routine can be called
1182 recursively, it needs to save and restore the contents of the jmp_buf as
1186 call_wrapper (clientData
, interp
, argc
, argv
)
1187 ClientData clientData
;
1192 struct wrapped_call_args wrapped_args
;
1193 Tcl_DString result
, *old_result_ptr
;
1194 Tcl_DString error_string
, *old_error_string_ptr
;
1196 Tcl_DStringInit (&result
);
1197 old_result_ptr
= result_ptr
;
1198 result_ptr
= &result
;
1200 Tcl_DStringInit (&error_string
);
1201 old_error_string_ptr
= error_string_ptr
;
1202 error_string_ptr
= &error_string
;
1204 wrapped_args
.func
= (Tcl_CmdProc
*)clientData
;
1205 wrapped_args
.interp
= interp
;
1206 wrapped_args
.argc
= argc
;
1207 wrapped_args
.argv
= argv
;
1208 wrapped_args
.val
= 0;
1210 if (!catch_errors (wrapped_call
, &wrapped_args
, "", RETURN_MASK_ALL
))
1212 wrapped_args
.val
= TCL_ERROR
; /* Flag an error for TCL */
1215 /* Make sure the timer interrupts are turned off. */
1216 if (gdbtk_timer_going
)
1217 gdbtk_stop_timer ();
1220 gdb_flush (gdb_stderr
); /* Flush error output */
1221 gdb_flush (gdb_stdout
); /* Sometimes error output comes here as well */
1223 /* In case of an error, we may need to force the GUI into idle
1224 mode because gdbtk_call_command may have bombed out while in
1225 the command routine. */
1228 Tcl_Eval (interp
, "gdbtk_tcl_idle");
1231 /* do not suppress any errors -- a remote target could have errored */
1232 load_in_progress
= 0;
1234 if (Tcl_DStringLength (&error_string
) == 0)
1236 Tcl_DStringResult (interp
, &result
);
1237 Tcl_DStringFree (&error_string
);
1239 else if (Tcl_DStringLength (&result
) == 0)
1241 Tcl_DStringResult (interp
, &error_string
);
1242 Tcl_DStringFree (&result
);
1243 Tcl_DStringFree (&error_string
);
1247 Tcl_ResetResult (interp
);
1248 Tcl_AppendResult (interp
, Tcl_DStringValue (&result
),
1249 Tcl_DStringValue (&error_string
), (char *) NULL
);
1250 Tcl_DStringFree (&result
);
1251 Tcl_DStringFree (&error_string
);
1254 result_ptr
= old_result_ptr
;
1255 error_string_ptr
= old_error_string_ptr
;
1261 return wrapped_args
.val
;
1265 comp_files (file1
, file2
)
1266 const char *file1
[], *file2
[];
1268 return strcmp(*file1
,*file2
);
1272 gdb_listfiles (clientData
, interp
, objc
, objv
)
1273 ClientData clientData
;
1276 Tcl_Obj
*CONST objv
[];
1278 struct objfile
*objfile
;
1279 struct partial_symtab
*psymtab
;
1280 struct symtab
*symtab
;
1281 char *lastfile
, *pathname
, *files
[1000];
1282 int i
, numfiles
= 0, len
= 0;
1287 Tcl_WrongNumArgs (interp
, 1, objv
, "Usage: gdb_listfiles ?pathname?");
1291 pathname
= Tcl_GetStringFromObj (objv
[1], &len
);
1293 mylist
= Tcl_NewListObj (0, NULL
);
1295 ALL_PSYMTABS (objfile
, psymtab
)
1299 if (psymtab
->filename
)
1300 files
[numfiles
++] = basename(psymtab
->filename
);
1302 else if (!strcmp(psymtab
->filename
,basename(psymtab
->filename
))
1303 || !strncmp(pathname
,psymtab
->filename
,len
))
1304 if (psymtab
->filename
)
1305 files
[numfiles
++] = basename(psymtab
->filename
);
1308 ALL_SYMTABS (objfile
, symtab
)
1312 if (symtab
->filename
)
1313 files
[numfiles
++] = basename(symtab
->filename
);
1315 else if (!strcmp(symtab
->filename
,basename(symtab
->filename
))
1316 || !strncmp(pathname
,symtab
->filename
,len
))
1317 if (symtab
->filename
)
1318 files
[numfiles
++] = basename(symtab
->filename
);
1321 qsort (files
, numfiles
, sizeof(char *), comp_files
);
1324 for (i
= 0; i
< numfiles
; i
++)
1326 if (strcmp(files
[i
],lastfile
))
1327 Tcl_ListObjAppendElement (interp
, mylist
, Tcl_NewStringObj(files
[i
], -1));
1328 lastfile
= files
[i
];
1330 Tcl_SetObjResult (interp
, mylist
);
1335 gdb_listfuncs (clientData
, interp
, argc
, argv
)
1336 ClientData clientData
;
1341 struct symtab
*symtab
;
1342 struct blockvector
*bv
;
1349 error ("wrong # args");
1351 symtab
= full_lookup_symtab (argv
[1]);
1353 error ("No such file");
1355 bv
= BLOCKVECTOR (symtab
);
1356 for (i
= GLOBAL_BLOCK
; i
<= STATIC_BLOCK
; i
++)
1358 b
= BLOCKVECTOR_BLOCK (bv
, i
);
1359 /* Skip the sort if this block is always sorted. */
1360 if (!BLOCK_SHOULD_SORT (b
))
1361 sort_block_syms (b
);
1362 for (j
= 0; j
< BLOCK_NSYMS (b
); j
++)
1364 sym
= BLOCK_SYM (b
, j
);
1365 if (SYMBOL_CLASS (sym
) == LOC_BLOCK
)
1368 char *name
= cplus_demangle (SYMBOL_NAME(sym
), 0);
1371 sprintf (buf
,"{%s} 1", name
);
1374 sprintf (buf
,"{%s} 0", SYMBOL_NAME(sym
));
1375 Tcl_DStringAppendElement (result_ptr
, buf
);
1383 target_stop_wrapper (args
)
1391 gdb_stop (clientData
, interp
, argc
, argv
)
1392 ClientData clientData
;
1399 catch_errors (target_stop_wrapper
, NULL
, "",
1403 quit_flag
= 1; /* hope something sees this */
1408 /* Prepare to accept a new executable file. This is called when we
1409 want to clear away everything we know about the old file, without
1410 asking the user. The Tcl code will have already asked the user if
1411 necessary. After this is called, we should be able to run the
1412 `file' command without getting any questions. */
1415 gdb_clear_file (clientData
, interp
, argc
, argv
)
1416 ClientData clientData
;
1421 if (inferior_pid
!= 0 && target_has_execution
)
1424 target_detach (NULL
, 0);
1429 if (target_has_execution
)
1432 symbol_file_command (NULL
, 0);
1434 /* gdb_loc refers to stop_pc, but nothing seems to clear it, so we
1435 clear it here. FIXME: This seems like an abstraction violation
1442 /* Ask the user to confirm an exit request. */
1445 gdb_confirm_quit (clientData
, interp
, argc
, argv
)
1446 ClientData clientData
;
1453 ret
= quit_confirm ();
1454 Tcl_DStringAppendElement (result_ptr
, ret
? "1" : "0");
1458 /* Quit without asking for confirmation. */
1461 gdb_force_quit (clientData
, interp
, argc
, argv
)
1462 ClientData clientData
;
1467 quit_force ((char *) NULL
, 1);
1471 /* This implements the TCL command `gdb_disassemble'. */
1474 gdbtk_dis_asm_read_memory (memaddr
, myaddr
, len
, info
)
1478 disassemble_info
*info
;
1480 extern struct target_ops exec_ops
;
1484 res
= xfer_memory (memaddr
, myaddr
, len
, 0, &exec_ops
);
1495 /* We need a different sort of line table from the normal one cuz we can't
1496 depend upon implicit line-end pc's for lines. This is because of the
1497 reordering we are about to do. */
1499 struct my_line_entry
{
1506 compare_lines (mle1p
, mle2p
)
1510 struct my_line_entry
*mle1
, *mle2
;
1513 mle1
= (struct my_line_entry
*) mle1p
;
1514 mle2
= (struct my_line_entry
*) mle2p
;
1516 val
= mle1
->line
- mle2
->line
;
1521 return mle1
->start_pc
- mle2
->start_pc
;
1525 gdb_disassemble (clientData
, interp
, argc
, argv
)
1526 ClientData clientData
;
1531 CORE_ADDR pc
, low
, high
;
1532 int mixed_source_and_assembly
;
1533 static disassemble_info di
;
1534 static int di_initialized
;
1536 if (! di_initialized
)
1538 INIT_DISASSEMBLE_INFO_NO_ARCH (di
, gdb_stdout
,
1539 (fprintf_ftype
) fprintf_unfiltered
);
1540 di
.flavour
= bfd_target_unknown_flavour
;
1541 di
.memory_error_func
= dis_asm_memory_error
;
1542 di
.print_address_func
= dis_asm_print_address
;
1546 di
.mach
= tm_print_insn_info
.mach
;
1547 if (TARGET_BYTE_ORDER
== BIG_ENDIAN
)
1548 di
.endian
= BFD_ENDIAN_BIG
;
1550 di
.endian
= BFD_ENDIAN_LITTLE
;
1552 if (argc
!= 3 && argc
!= 4)
1553 error ("wrong # args");
1555 if (strcmp (argv
[1], "source") == 0)
1556 mixed_source_and_assembly
= 1;
1557 else if (strcmp (argv
[1], "nosource") == 0)
1558 mixed_source_and_assembly
= 0;
1560 error ("First arg must be 'source' or 'nosource'");
1562 low
= parse_and_eval_address (argv
[2]);
1566 if (find_pc_partial_function (low
, NULL
, &low
, &high
) == 0)
1567 error ("No function contains specified address");
1570 high
= parse_and_eval_address (argv
[3]);
1572 /* If disassemble_from_exec == -1, then we use the following heuristic to
1573 determine whether or not to do disassembly from target memory or from the
1576 If we're debugging a local process, read target memory, instead of the
1577 exec file. This makes disassembly of functions in shared libs work
1580 Else, we're debugging a remote process, and should disassemble from the
1581 exec file for speed. However, this is no good if the target modifies its
1582 code (for relocation, or whatever).
1585 if (disassemble_from_exec
== -1)
1586 if (strcmp (target_shortname
, "child") == 0
1587 || strcmp (target_shortname
, "procfs") == 0
1588 || strcmp (target_shortname
, "vxprocess") == 0)
1589 disassemble_from_exec
= 0; /* It's a child process, read inferior mem */
1591 disassemble_from_exec
= 1; /* It's remote, read the exec file */
1593 if (disassemble_from_exec
)
1594 di
.read_memory_func
= gdbtk_dis_asm_read_memory
;
1596 di
.read_memory_func
= dis_asm_read_memory
;
1598 /* If just doing straight assembly, all we need to do is disassemble
1599 everything between low and high. If doing mixed source/assembly, we've
1600 got a totally different path to follow. */
1602 if (mixed_source_and_assembly
)
1603 { /* Come here for mixed source/assembly */
1604 /* The idea here is to present a source-O-centric view of a function to
1605 the user. This means that things are presented in source order, with
1606 (possibly) out of order assembly immediately following. */
1607 struct symtab
*symtab
;
1608 struct linetable_entry
*le
;
1611 struct my_line_entry
*mle
;
1612 struct symtab_and_line sal
;
1617 symtab
= find_pc_symtab (low
); /* Assume symtab is valid for whole PC range */
1622 /* First, convert the linetable to a bunch of my_line_entry's. */
1624 le
= symtab
->linetable
->item
;
1625 nlines
= symtab
->linetable
->nitems
;
1630 mle
= (struct my_line_entry
*) alloca (nlines
* sizeof (struct my_line_entry
));
1634 /* Copy linetable entries for this function into our data structure, creating
1635 end_pc's and setting out_of_order as appropriate. */
1637 /* First, skip all the preceding functions. */
1639 for (i
= 0; i
< nlines
- 1 && le
[i
].pc
< low
; i
++) ;
1641 /* Now, copy all entries before the end of this function. */
1644 for (; i
< nlines
- 1 && le
[i
].pc
< high
; i
++)
1646 if (le
[i
].line
== le
[i
+ 1].line
1647 && le
[i
].pc
== le
[i
+ 1].pc
)
1648 continue; /* Ignore duplicates */
1650 mle
[newlines
].line
= le
[i
].line
;
1651 if (le
[i
].line
> le
[i
+ 1].line
)
1653 mle
[newlines
].start_pc
= le
[i
].pc
;
1654 mle
[newlines
].end_pc
= le
[i
+ 1].pc
;
1658 /* If we're on the last line, and it's part of the function, then we need to
1659 get the end pc in a special way. */
1664 mle
[newlines
].line
= le
[i
].line
;
1665 mle
[newlines
].start_pc
= le
[i
].pc
;
1666 sal
= find_pc_line (le
[i
].pc
, 0);
1667 mle
[newlines
].end_pc
= sal
.end
;
1671 /* Now, sort mle by line #s (and, then by addresses within lines). */
1674 qsort (mle
, newlines
, sizeof (struct my_line_entry
), compare_lines
);
1676 /* Now, for each line entry, emit the specified lines (unless they have been
1677 emitted before), followed by the assembly code for that line. */
1679 next_line
= 0; /* Force out first line */
1680 for (i
= 0; i
< newlines
; i
++)
1682 /* Print out everything from next_line to the current line. */
1684 if (mle
[i
].line
>= next_line
)
1687 print_source_lines (symtab
, next_line
, mle
[i
].line
+ 1, 0);
1689 print_source_lines (symtab
, mle
[i
].line
, mle
[i
].line
+ 1, 0);
1691 next_line
= mle
[i
].line
+ 1;
1694 for (pc
= mle
[i
].start_pc
; pc
< mle
[i
].end_pc
; )
1697 fputs_unfiltered (" ", gdb_stdout
);
1698 print_address (pc
, gdb_stdout
);
1699 fputs_unfiltered (":\t ", gdb_stdout
);
1700 pc
+= (*tm_print_insn
) (pc
, &di
);
1701 fputs_unfiltered ("\n", gdb_stdout
);
1708 for (pc
= low
; pc
< high
; )
1711 fputs_unfiltered (" ", gdb_stdout
);
1712 print_address (pc
, gdb_stdout
);
1713 fputs_unfiltered (":\t ", gdb_stdout
);
1714 pc
+= (*tm_print_insn
) (pc
, &di
);
1715 fputs_unfiltered ("\n", gdb_stdout
);
1719 gdb_flush (gdb_stdout
);
1725 tk_command (cmd
, from_tty
)
1731 struct cleanup
*old_chain
;
1733 /* Catch case of no argument, since this will make the tcl interpreter dump core. */
1735 error_no_arg ("tcl command to interpret");
1737 retval
= Tcl_Eval (interp
, cmd
);
1739 result
= strdup (interp
->result
);
1741 old_chain
= make_cleanup (free
, result
);
1743 if (retval
!= TCL_OK
)
1746 printf_unfiltered ("%s\n", result
);
1748 do_cleanups (old_chain
);
1752 cleanup_init (ignored
)
1756 Tcl_DeleteInterp (interp
);
1760 /* Come here during long calculations to check for GUI events. Usually invoked
1761 via the QUIT macro. */
1764 gdbtk_interactive ()
1766 /* Tk_DoOneEvent (TK_DONT_WAIT|TK_IDLE_EVENTS); */
1769 /* Come here when there is activity on the X file descriptor. */
1775 static int in_x_event
= 0;
1776 static Tcl_Obj
*varname
= NULL
;
1778 if (in_x_event
|| in_fputs
)
1783 /* Process pending events */
1784 while (Tcl_DoOneEvent (TCL_DONT_WAIT
|TCL_ALL_EVENTS
) != 0)
1787 if (load_in_progress
)
1790 if (varname
== NULL
)
1792 Tcl_Obj
*varnamestrobj
= Tcl_NewStringObj("download_cancel_ok",-1);
1793 varname
= Tcl_ObjGetVar2(interp
,varnamestrobj
,NULL
,TCL_GLOBAL_ONLY
);
1795 if ((Tcl_GetIntFromObj(interp
,varname
,&val
) == TCL_OK
) && val
)
1811 /* For Cygwin32, we use a timer to periodically check for Windows
1812 messages. FIXME: It would be better to not poll, but to instead
1813 rewrite the target_wait routines to serve as input sources.
1814 Unfortunately, that will be a lot of work. */
1815 static sigset_t nullsigmask
;
1816 static struct sigaction act1
, act2
;
1817 static struct itimerval it_on
, it_off
;
1820 gdbtk_start_timer ()
1822 static int first
= 1;
1823 /*TclDebug ("Starting timer....");*/
1826 /* first time called, set up all the structs */
1828 sigemptyset (&nullsigmask
);
1830 act1
.sa_handler
= x_event
;
1831 act1
.sa_mask
= nullsigmask
;
1834 act2
.sa_handler
= SIG_IGN
;
1835 act2
.sa_mask
= nullsigmask
;
1838 it_on
.it_interval
.tv_sec
= 0;
1839 it_on
.it_interval
.tv_usec
= 500000; /* .5 sec */
1840 it_on
.it_value
.tv_sec
= 0;
1841 it_on
.it_value
.tv_usec
= 500000;
1843 it_off
.it_interval
.tv_sec
= 0;
1844 it_off
.it_interval
.tv_usec
= 0;
1845 it_off
.it_value
.tv_sec
= 0;
1846 it_off
.it_value
.tv_usec
= 0;
1848 sigaction (SIGALRM
, &act1
, NULL
);
1849 setitimer (ITIMER_REAL
, &it_on
, NULL
);
1850 gdbtk_timer_going
= 1;
1856 gdbtk_timer_going
= 0;
1857 /*TclDebug ("Stopping timer.");*/
1858 setitimer (ITIMER_REAL
, &it_off
, NULL
);
1859 sigaction (SIGALRM
, &act2
, NULL
);
1864 /* This hook function is called whenever we want to wait for the
1868 gdbtk_wait (pid
, ourstatus
)
1870 struct target_waitstatus
*ourstatus
;
1873 struct sigaction action
;
1874 static sigset_t nullsigmask
= {0};
1878 /* Needed for SunOS 4.1.x */
1879 #define SA_RESTART 0
1882 action
.sa_handler
= x_event
;
1883 action
.sa_mask
= nullsigmask
;
1884 action
.sa_flags
= SA_RESTART
;
1885 sigaction(SIGIO
, &action
, NULL
);
1888 pid
= target_wait (pid
, ourstatus
);
1891 action
.sa_handler
= SIG_IGN
;
1892 sigaction(SIGIO
, &action
, NULL
);
1898 /* This is called from execute_command, and provides a wrapper around
1899 various command routines in a place where both protocol messages and
1900 user input both flow through. Mostly this is used for indicating whether
1901 the target process is running or not.
1905 gdbtk_call_command (cmdblk
, arg
, from_tty
)
1906 struct cmd_list_element
*cmdblk
;
1911 if (cmdblk
->class == class_run
|| cmdblk
->class == class_trace
)
1915 Tcl_Eval (interp
, "gdbtk_tcl_busy");
1916 (*cmdblk
->function
.cfunc
)(arg
, from_tty
);
1919 Tcl_Eval (interp
, "gdbtk_tcl_idle");
1922 (*cmdblk
->function
.cfunc
)(arg
, from_tty
);
1925 /* This function is called instead of gdb's internal command loop. This is the
1926 last chance to do anything before entering the main Tk event loop. */
1931 extern GDB_FILE
*instream
;
1933 /* We no longer want to use stdin as the command input stream */
1936 if (Tcl_Eval (interp
, "gdbtk_tcl_preloop") != TCL_OK
)
1940 /* Force errorInfo to be set up propertly. */
1941 Tcl_AddErrorInfo (interp
, "");
1943 msg
= Tcl_GetVar (interp
, "errorInfo", TCL_GLOBAL_ONLY
);
1945 MessageBox (NULL
, msg
, NULL
, MB_OK
| MB_ICONERROR
| MB_TASKMODAL
);
1947 fputs_unfiltered (msg
, gdb_stderr
);
1958 /* gdbtk_init installs this function as a final cleanup. */
1961 gdbtk_cleanup (dummy
)
1965 struct ide_event_handle
*h
= (struct ide_event_handle
*) dummy
;
1967 ide_interface_deregister_all (h
);
1972 /* Initialize gdbtk. */
1975 gdbtk_init ( argv0
)
1978 struct cleanup
*old_chain
;
1979 char *lib
, *gdbtk_lib
, *gdbtk_lib_tmp
, *gdbtk_file
;
1982 struct sigaction action
;
1983 static sigset_t nullsigmask
= {0};
1986 /* start-sanitize-ide */
1987 struct ide_event_handle
*h
;
1990 /* end-sanitize-ide */
1993 /* If there is no DISPLAY environment variable, Tk_Init below will fail,
1994 causing gdb to abort. If instead we simply return here, gdb will
1995 gracefully degrade to using the command line interface. */
1998 if (getenv ("DISPLAY") == NULL
)
2002 old_chain
= make_cleanup (cleanup_init
, 0);
2004 /* First init tcl and tk. */
2005 Tcl_FindExecutable (argv0
);
2006 interp
= Tcl_CreateInterp ();
2008 #ifdef TCL_MEM_DEBUG
2009 Tcl_InitMemory (interp
);
2013 error ("Tcl_CreateInterp failed");
2015 if (Tcl_Init(interp
) != TCL_OK
)
2016 error ("Tcl_Init failed: %s", interp
->result
);
2019 /* For the IDE we register the cleanup later, after we've
2020 initialized events. */
2021 make_final_cleanup (gdbtk_cleanup
, NULL
);
2024 /* Initialize the Paths variable. */
2025 if (ide_initialize_paths (interp
, "gdbtcl") != TCL_OK
)
2026 error ("ide_initialize_paths failed: %s", interp
->result
);
2029 /* start-sanitize-ide */
2030 /* Find the directory where we expect to find idemanager. We ignore
2031 errors since it doesn't really matter if this fails. */
2032 libexecdir
= Tcl_GetVar2 (interp
, "Paths", "libexecdir", TCL_GLOBAL_ONLY
);
2036 h
= ide_event_init_from_environment (&errmsg
, libexecdir
);
2037 make_final_cleanup (gdbtk_cleanup
, h
);
2040 Tcl_AppendResult (interp
, "can't initialize event system: ", errmsg
,
2042 fprintf(stderr
, "WARNING: ide_event_init_client failed: %s\n", interp
->result
);
2044 Tcl_SetVar (interp
, "GDBTK_IDE", "0", 0);
2048 if (ide_create_tclevent_command (interp
, h
) != TCL_OK
)
2049 error ("ide_create_tclevent_command failed: %s", interp
->result
);
2051 if (ide_create_edit_command (interp
, h
) != TCL_OK
)
2052 error ("ide_create_edit_command failed: %s", interp
->result
);
2054 if (ide_create_property_command (interp
, h
) != TCL_OK
)
2055 error ("ide_create_property_command failed: %s", interp
->result
);
2057 if (ide_create_build_command (interp
, h
) != TCL_OK
)
2058 error ("ide_create_build_command failed: %s", interp
->result
);
2060 if (ide_create_window_register_command (interp
, h
, "gdb-restore")
2062 error ("ide_create_window_register_command failed: %s",
2065 if (ide_create_window_command (interp
, h
) != TCL_OK
)
2066 error ("ide_create_window_command failed: %s", interp
->result
);
2068 if (ide_create_exit_command (interp
, h
) != TCL_OK
)
2069 error ("ide_create_exit_command failed: %s", interp
->result
);
2071 if (ide_create_help_command (interp
) != TCL_OK
)
2072 error ("ide_create_help_command failed: %s", interp
->result
);
2075 if (ide_initialize (interp, "gdb") != TCL_OK)
2076 error ("ide_initialize failed: %s", interp->result);
2079 Tcl_SetVar (interp
, "GDBTK_IDE", "1", 0);
2081 /* end-sanitize-ide */
2083 Tcl_SetVar (interp
, "GDBTK_IDE", "0", 0);
2086 /* We don't want to open the X connection until we've done all the
2087 IDE initialization. Otherwise, goofy looking unfinished windows
2088 pop up when ILU drops into the TCL event loop. */
2090 if (Tk_Init(interp
) != TCL_OK
)
2091 error ("Tk_Init failed: %s", interp
->result
);
2093 if (Itcl_Init(interp
) == TCL_ERROR
)
2094 error ("Itcl_Init failed: %s", interp
->result
);
2096 if (Tix_Init(interp
) != TCL_OK
)
2097 error ("Tix_Init failed: %s", interp
->result
);
2100 if (ide_create_messagebox_command (interp
) != TCL_OK
)
2101 error ("messagebox command initialization failed");
2102 /* On Windows, create a sizebox widget command */
2103 if (ide_create_sizebox_command (interp
) != TCL_OK
)
2104 error ("sizebox creation failed");
2105 if (ide_create_winprint_command (interp
) != TCL_OK
)
2106 error ("windows print code initialization failed");
2107 /* start-sanitize-ide */
2108 /* An interface to ShellExecute. */
2109 if (ide_create_shell_execute_command (interp
) != TCL_OK
)
2110 error ("shell execute command initialization failed");
2111 /* end-sanitize-ide */
2112 if (ide_create_win_grab_command (interp
) != TCL_OK
)
2113 error ("grab support command initialization failed");
2114 /* Path conversion functions. */
2115 if (ide_create_cygwin_path_command (interp
) != TCL_OK
)
2116 error ("cygwin path command initialization failed");
2119 Tcl_CreateCommand (interp
, "gdb_cmd", call_wrapper
, gdb_cmd
, NULL
);
2120 Tcl_CreateCommand (interp
, "gdb_immediate", call_wrapper
,
2121 gdb_immediate_command
, NULL
);
2122 Tcl_CreateCommand (interp
, "gdb_loc", call_wrapper
, gdb_loc
, NULL
);
2123 Tcl_CreateCommand (interp
, "gdb_path_conv", call_wrapper
, gdb_path_conv
, NULL
);
2124 Tcl_CreateObjCommand (interp
, "gdb_listfiles", gdb_listfiles
, NULL
, NULL
);
2125 Tcl_CreateCommand (interp
, "gdb_listfuncs", call_wrapper
, gdb_listfuncs
,
2127 Tcl_CreateCommand (interp
, "gdb_get_mem", call_wrapper
, gdb_get_mem
,
2129 Tcl_CreateCommand (interp
, "gdb_stop", call_wrapper
, gdb_stop
, NULL
);
2130 Tcl_CreateCommand (interp
, "gdb_regnames", call_wrapper
, gdb_regnames
, NULL
);
2131 Tcl_CreateCommand (interp
, "gdb_fetch_registers", call_wrapper
,
2132 gdb_fetch_registers
, NULL
);
2133 Tcl_CreateCommand (interp
, "gdb_changed_register_list", call_wrapper
,
2134 gdb_changed_register_list
, NULL
);
2135 Tcl_CreateCommand (interp
, "gdb_disassemble", call_wrapper
,
2136 gdb_disassemble
, NULL
);
2137 Tcl_CreateCommand (interp
, "gdb_eval", call_wrapper
, gdb_eval
, NULL
);
2138 Tcl_CreateCommand (interp
, "gdb_get_breakpoint_list", call_wrapper
,
2139 gdb_get_breakpoint_list
, NULL
);
2140 Tcl_CreateCommand (interp
, "gdb_get_breakpoint_info", call_wrapper
,
2141 gdb_get_breakpoint_info
, NULL
);
2142 Tcl_CreateCommand (interp
, "gdb_clear_file", call_wrapper
,
2143 gdb_clear_file
, NULL
);
2144 Tcl_CreateCommand (interp
, "gdb_confirm_quit", call_wrapper
,
2145 gdb_confirm_quit
, NULL
);
2146 Tcl_CreateCommand (interp
, "gdb_force_quit", call_wrapper
,
2147 gdb_force_quit
, NULL
);
2148 Tcl_CreateCommand (interp
, "gdb_target_has_execution",
2149 gdb_target_has_execution_command
,
2151 Tcl_CreateCommand (interp
, "gdb_is_tracing",
2154 Tcl_CreateObjCommand (interp
, "gdb_load_info", gdb_load_info
, NULL
, NULL
);
2155 Tcl_CreateObjCommand (interp
, "gdb_get_locals", gdb_get_vars_command
,
2156 (ClientData
) 0, NULL
);
2157 Tcl_CreateObjCommand (interp
, "gdb_get_args", gdb_get_vars_command
,
2158 (ClientData
) 1, NULL
);
2159 Tcl_CreateObjCommand (interp
, "gdb_get_function", gdb_get_function_command
,
2161 Tcl_CreateObjCommand (interp
, "gdb_get_line", gdb_get_line_command
,
2163 Tcl_CreateObjCommand (interp
, "gdb_get_file", gdb_get_file_command
,
2165 Tcl_CreateObjCommand (interp
, "gdb_tracepoint_exists",
2166 gdb_tracepoint_exists_command
, NULL
, NULL
);
2167 Tcl_CreateObjCommand (interp
, "gdb_get_tracepoint_info",
2168 gdb_get_tracepoint_info
, NULL
, NULL
);
2169 Tcl_CreateObjCommand (interp
, "gdb_actions",
2170 gdb_actions_command
, NULL
, NULL
);
2171 Tcl_CreateObjCommand (interp
, "gdb_prompt",
2172 gdb_prompt_command
, NULL
, NULL
);
2173 Tcl_CreateObjCommand (interp
, "gdb_find_file",
2174 gdb_find_file_command
, NULL
, NULL
);
2175 Tcl_CreateObjCommand (interp
, "gdb_get_tracepoint_list",
2176 gdb_get_tracepoint_list
, NULL
, NULL
);
2177 Tcl_CreateCommand (interp
, "gdb_pc_reg", get_pc_register
, NULL
, NULL
);
2178 Tcl_CreateObjCommand (interp
, "gdb_loadfile", gdb_loadfile
, NULL
, NULL
);
2179 Tcl_CreateObjCommand (interp
, "gdb_set_bp", gdb_set_bp
, NULL
, NULL
);
2181 command_loop_hook
= tk_command_loop
;
2182 print_frame_info_listing_hook
= gdbtk_print_frame_info
;
2183 query_hook
= gdbtk_query
;
2184 flush_hook
= gdbtk_flush
;
2185 create_breakpoint_hook
= gdbtk_create_breakpoint
;
2186 delete_breakpoint_hook
= gdbtk_delete_breakpoint
;
2187 modify_breakpoint_hook
= gdbtk_modify_breakpoint
;
2188 interactive_hook
= gdbtk_interactive
;
2189 target_wait_hook
= gdbtk_wait
;
2190 call_command_hook
= gdbtk_call_command
;
2191 readline_begin_hook
= gdbtk_readline_begin
;
2192 readline_hook
= gdbtk_readline
;
2193 readline_end_hook
= gdbtk_readline_end
;
2194 ui_load_progress_hook
= gdbtk_load_hash
;
2195 pre_add_symbol_hook
= gdbtk_pre_add_symbol
;
2196 post_add_symbol_hook
= gdbtk_post_add_symbol
;
2197 create_tracepoint_hook
= gdbtk_create_tracepoint
;
2198 delete_tracepoint_hook
= gdbtk_delete_tracepoint
;
2199 modify_tracepoint_hook
= gdbtk_modify_tracepoint
;
2200 pc_changed_hook
= pc_changed
;
2202 annotate_starting_hook
= gdbtk_annotate_starting
;
2203 annotate_stopped_hook
= gdbtk_annotate_stopped
;
2204 annotate_signalled_hook
= gdbtk_annotate_signalled
;
2205 annotate_exited_hook
= gdbtk_annotate_exited
;
2206 ui_loop_hook
= x_event
;
2209 /* Get the file descriptor for the X server */
2211 x_fd
= ConnectionNumber (Tk_Display (Tk_MainWindow (interp
)));
2213 /* Setup for I/O interrupts */
2215 action
.sa_mask
= nullsigmask
;
2216 action
.sa_flags
= 0;
2217 action
.sa_handler
= SIG_IGN
;
2218 sigaction(SIGIO
, &action
, NULL
);
2222 if (ioctl (x_fd
, FIOASYNC
, &i
))
2223 perror_with_name ("gdbtk_init: ioctl FIOASYNC failed");
2227 if (ioctl (x_fd
, SIOCSPGRP
, &i
))
2228 perror_with_name ("gdbtk_init: ioctl SIOCSPGRP failed");
2233 if (fcntl (x_fd
, F_SETOWN
, i
))
2234 perror_with_name ("gdbtk_init: fcntl F_SETOWN failed");
2235 #endif /* F_SETOWN */
2236 #endif /* !SIOCSPGRP */
2239 if (ioctl (x_fd
, I_SETSIG
, S_INPUT
|S_RDNORM
) < 0)
2240 perror_with_name ("gdbtk_init: ioctl I_SETSIG failed");
2243 #endif /* ifndef FIOASYNC */
2246 add_com ("tk", class_obscure
, tk_command
,
2247 "Send a command directly into tk.");
2249 Tcl_LinkVar (interp
, "disassemble-from-exec", (char *)&disassemble_from_exec
,
2252 /* find the gdb tcl library and source main.tcl */
2254 gdbtk_lib
= getenv ("GDBTK_LIBRARY");
2256 if (access ("gdbtcl/main.tcl", R_OK
) == 0)
2257 gdbtk_lib
= "gdbtcl";
2259 gdbtk_lib
= GDBTK_LIBRARY
;
2261 gdbtk_lib_tmp
= xstrdup (gdbtk_lib
);
2264 /* see if GDBTK_LIBRARY is a path list */
2265 lib
= strtok (gdbtk_lib_tmp
, GDBTK_PATH_SEP
);
2268 if (Tcl_VarEval (interp
, "lappend auto_path ", lib
, NULL
) != TCL_OK
)
2270 fputs_unfiltered (Tcl_GetVar (interp
, "errorInfo", 0), gdb_stderr
);
2275 gdbtk_file
= concat (lib
, "/main.tcl", (char *) NULL
);
2276 if (access (gdbtk_file
, R_OK
) == 0)
2279 Tcl_SetVar (interp
, "GDBTK_LIBRARY", lib
, 0);
2283 while ((lib
= strtok (NULL
, ":")) != NULL
);
2285 free (gdbtk_lib_tmp
);
2289 /* Try finding it with the auto path. */
2291 static const char script
[] ="\
2292 proc gdbtk_find_main {} {\n\
2293 global auto_path GDBTK_LIBRARY\n\
2294 foreach dir $auto_path {\n\
2295 set f [file join $dir main.tcl]\n\
2296 if {[file exists $f]} then {\n\
2297 set GDBTK_LIBRARY $dir\n\
2305 if (Tcl_GlobalEval (interp
, (char *) script
) != TCL_OK
)
2307 fputs_unfiltered (Tcl_GetVar (interp
, "errorInfo", 0), gdb_stderr
);
2311 if (interp
->result
[0] != '\0')
2313 gdbtk_file
= xstrdup (interp
->result
);
2320 fputs_unfiltered_hook
= NULL
; /* Force errors to stdout/stderr */
2321 if (getenv("GDBTK_LIBRARY"))
2323 fprintf_unfiltered (stderr
, "Unable to find main.tcl in %s\n",getenv("GDBTK_LIBRARY"));
2324 fprintf_unfiltered (stderr
,
2325 "Please set GDBTK_LIBRARY to a path that includes the GDB tcl files.\n");
2329 fprintf_unfiltered (stderr
, "Unable to find main.tcl in %s\n", GDBTK_LIBRARY
);
2330 fprintf_unfiltered (stderr
, "You might want to set GDBTK_LIBRARY\n");
2335 /* Defer setup of fputs_unfiltered_hook to near the end so that error messages
2336 prior to this point go to stdout/stderr. */
2338 fputs_unfiltered_hook
= gdbtk_fputs
;
2340 if (Tcl_EvalFile (interp
, gdbtk_file
) != TCL_OK
)
2344 /* Force errorInfo to be set up propertly. */
2345 Tcl_AddErrorInfo (interp
, "");
2347 msg
= Tcl_GetVar (interp
, "errorInfo", TCL_GLOBAL_ONLY
);
2349 fputs_unfiltered_hook
= NULL
; /* Force errors to stdout/stderr */
2352 MessageBox (NULL
, msg
, NULL
, MB_OK
| MB_ICONERROR
| MB_TASKMODAL
);
2354 fputs_unfiltered (msg
, gdb_stderr
);
2361 /* start-sanitize-ide */
2362 /* Don't do this until we have initialized. Otherwise, we may get a
2363 run command before we are ready for one. */
2364 if (ide_run_server_init (interp
, h
) != TCL_OK
)
2365 error ("ide_run_server_init failed: %s", interp
->result
);
2366 /* end-sanitize-ide */
2371 discard_cleanups (old_chain
);
2375 gdb_target_has_execution_command (clientData
, interp
, argc
, argv
)
2376 ClientData clientData
;
2383 if (target_has_execution
&& inferior_pid
!= 0)
2386 Tcl_SetIntObj (Tcl_GetObjResult (interp
), result
);
2391 gdb_trace_status (clientData
, interp
, argc
, argv
)
2392 ClientData clientData
;
2399 if (trace_running_p
)
2402 Tcl_SetIntObj (Tcl_GetObjResult (interp
), result
);
2406 /* gdb_load_info - returns information about the file about to be downloaded */
2409 gdb_load_info (clientData
, interp
, objc
, objv
)
2410 ClientData clientData
;
2413 Tcl_Obj
*CONST objv
[];
2416 struct cleanup
*old_cleanups
;
2422 char *filename
= Tcl_GetStringFromObj (objv
[1], NULL
);
2424 loadfile_bfd
= bfd_openr (filename
, gnutarget
);
2425 if (loadfile_bfd
== NULL
)
2427 Tcl_SetObjResult (interp
, Tcl_NewStringObj ("Open failed", -1));
2430 old_cleanups
= make_cleanup (bfd_close
, loadfile_bfd
);
2432 if (!bfd_check_format (loadfile_bfd
, bfd_object
))
2434 Tcl_SetObjResult (interp
, Tcl_NewStringObj ("Bad Object File", -1));
2438 for (s
= loadfile_bfd
->sections
; s
; s
= s
->next
)
2440 if (s
->flags
& SEC_LOAD
)
2442 bfd_size_type size
= bfd_get_section_size_before_reloc (s
);
2445 ob
[0] = Tcl_NewStringObj((char *)bfd_get_section_name(loadfile_bfd
, s
), -1);
2446 ob
[1] = Tcl_NewLongObj ((long)size
);
2447 res
[i
++] = Tcl_NewListObj (2, ob
);
2452 Tcl_SetObjResult (interp
, Tcl_NewListObj (i
, res
));
2453 do_cleanups (old_cleanups
);
2459 gdbtk_load_hash (section
, num
)
2464 sprintf (buf
, "download_hash %s %ld", section
, num
);
2465 Tcl_Eval (interp
, buf
);
2466 return atoi (interp
->result
);
2469 /* gdb_get_vars_command -
2471 * Implements the "gdb_get_locals" and "gdb_get_args" tcl commands. This
2472 * function sets the Tcl interpreter's result to a list of variable names
2473 * depending on clientData. If clientData is one, the result is a list of
2474 * arguments; zero returns a list of locals -- all relative to the block
2475 * specified as an argument to the command. Valid commands include
2476 * anything decode_line_1 can handle (like "main.c:2", "*0x02020202",
2480 gdb_get_vars_command (clientData
, interp
, objc
, objv
)
2481 ClientData clientData
;
2484 Tcl_Obj
*CONST objv
[];
2487 struct symtabs_and_lines sals
;
2489 struct block
*block
;
2490 char **canonical
, *args
;
2491 int i
, nsyms
, arguments
;
2495 Tcl_AppendResult (interp
,
2496 "wrong # of args: should be \"",
2497 Tcl_GetStringFromObj (objv
[0], NULL
),
2498 " function:line|function|line|*addr\"");
2502 arguments
= (int) clientData
;
2503 args
= Tcl_GetStringFromObj (objv
[1], NULL
);
2504 sals
= decode_line_1 (&args
, 1, NULL
, 0, &canonical
);
2505 if (sals
.nelts
== 0)
2507 Tcl_AppendResult (interp
,
2508 "error decoding line", NULL
);
2512 /* Initialize a list that will hold the results */
2513 result
= Tcl_NewListObj (0, NULL
);
2515 /* Resolve all line numbers to PC's */
2516 for (i
= 0; i
< sals
.nelts
; i
++)
2517 resolve_sal_pc (&sals
.sals
[i
]);
2519 block
= block_for_pc (sals
.sals
[0].pc
);
2522 nsyms
= BLOCK_NSYMS (block
);
2523 for (i
= 0; i
< nsyms
; i
++)
2525 sym
= BLOCK_SYM (block
, i
);
2526 switch (SYMBOL_CLASS (sym
)) {
2528 case LOC_UNDEF
: /* catches errors */
2529 case LOC_CONST
: /* constant */
2530 case LOC_STATIC
: /* static */
2531 case LOC_REGISTER
: /* register */
2532 case LOC_TYPEDEF
: /* local typedef */
2533 case LOC_LABEL
: /* local label */
2534 case LOC_BLOCK
: /* local function */
2535 case LOC_CONST_BYTES
: /* loc. byte seq. */
2536 case LOC_UNRESOLVED
: /* unresolved static */
2537 case LOC_OPTIMIZED_OUT
: /* optimized out */
2539 case LOC_ARG
: /* argument */
2540 case LOC_REF_ARG
: /* reference arg */
2541 case LOC_REGPARM
: /* register arg */
2542 case LOC_REGPARM_ADDR
: /* indirect register arg */
2543 case LOC_LOCAL_ARG
: /* stack arg */
2544 case LOC_BASEREG_ARG
: /* basereg arg */
2546 Tcl_ListObjAppendElement (interp
, result
,
2547 Tcl_NewStringObj (SYMBOL_NAME (sym
), -1));
2549 case LOC_LOCAL
: /* stack local */
2550 case LOC_BASEREG
: /* basereg local */
2552 Tcl_ListObjAppendElement (interp
, result
,
2553 Tcl_NewStringObj (SYMBOL_NAME (sym
), -1));
2557 if (BLOCK_FUNCTION (block
))
2560 block
= BLOCK_SUPERBLOCK (block
);
2563 Tcl_SetObjResult (interp
, result
);
2568 gdb_get_line_command (clientData
, interp
, objc
, objv
)
2569 ClientData clientData
;
2572 Tcl_Obj
*CONST objv
[];
2575 struct symtabs_and_lines sals
;
2576 char *args
, **canonical
;
2580 Tcl_AppendResult (interp
, "wrong # of args: should be \"",
2581 Tcl_GetStringFromObj (objv
[0], NULL
),
2586 args
= Tcl_GetStringFromObj (objv
[1], NULL
);
2587 sals
= decode_line_1 (&args
, 1, NULL
, 0, &canonical
);
2588 if (sals
.nelts
== 1)
2590 Tcl_SetObjResult (interp
, Tcl_NewIntObj (sals
.sals
[0].line
));
2594 Tcl_SetResult (interp
, "N/A", TCL_STATIC
);
2599 gdb_get_file_command (clientData
, interp
, objc
, objv
)
2600 ClientData clientData
;
2603 Tcl_Obj
*CONST objv
[];
2606 struct symtabs_and_lines sals
;
2607 char *args
, **canonical
;
2611 Tcl_AppendResult (interp
, "wrong # of args: should be \"",
2612 Tcl_GetStringFromObj (objv
[0], NULL
),
2617 args
= Tcl_GetStringFromObj (objv
[1], NULL
);
2618 sals
= decode_line_1 (&args
, 1, NULL
, 0, &canonical
);
2619 if (sals
.nelts
== 1)
2621 Tcl_SetResult (interp
, sals
.sals
[0].symtab
->filename
, TCL_VOLATILE
);
2625 Tcl_SetResult (interp
, "N/A", TCL_STATIC
);
2630 gdb_get_function_command (clientData
, interp
, objc
, objv
)
2631 ClientData clientData
;
2634 Tcl_Obj
*CONST objv
[];
2638 struct symtabs_and_lines sals
;
2639 char *args
, **canonical
;
2643 Tcl_AppendResult (interp
, "wrong # of args: should be \"",
2644 Tcl_GetStringFromObj (objv
[0], NULL
),
2649 args
= Tcl_GetStringFromObj (objv
[1], NULL
);
2650 sals
= decode_line_1 (&args
, 1, NULL
, 0, &canonical
);
2651 if (sals
.nelts
== 1)
2653 resolve_sal_pc (&sals
.sals
[0]);
2654 find_pc_partial_function (sals
.sals
[0].pc
, &function
, NULL
, NULL
);
2655 if (function
!= NULL
)
2657 Tcl_SetResult (interp
, function
, TCL_VOLATILE
);
2662 Tcl_SetResult (interp
, "N/A", TCL_STATIC
);
2667 gdb_get_tracepoint_info (clientData
, interp
, objc
, objv
)
2668 ClientData clientData
;
2671 Tcl_Obj
*CONST objv
[];
2673 struct symtab_and_line sal
;
2675 struct tracepoint
*tp
;
2676 struct action_line
*al
;
2677 Tcl_Obj
*list
, *action_list
;
2678 char *filename
, *funcname
;
2682 error ("wrong # args");
2684 Tcl_GetIntFromObj (NULL
, objv
[1], &tpnum
);
2686 ALL_TRACEPOINTS (tp
)
2687 if (tp
->number
== tpnum
)
2691 error ("Tracepoint #%d does not exist", tpnum
);
2693 list
= Tcl_NewListObj (0, NULL
);
2694 sal
= find_pc_line (tp
->address
, 0);
2695 filename
= symtab_to_filename (sal
.symtab
);
2696 if (filename
== NULL
)
2698 Tcl_ListObjAppendElement (interp
, list
,
2699 Tcl_NewStringObj (filename
, -1));
2700 find_pc_partial_function (tp
->address
, &funcname
, NULL
, NULL
);
2701 Tcl_ListObjAppendElement (interp
, list
, Tcl_NewStringObj (funcname
, -1));
2702 Tcl_ListObjAppendElement (interp
, list
, Tcl_NewIntObj (sal
.line
));
2703 sprintf (tmp
, "0x%lx", tp
->address
);
2704 Tcl_ListObjAppendElement (interp
, list
, Tcl_NewStringObj (tmp
, -1));
2705 Tcl_ListObjAppendElement (interp
, list
, Tcl_NewIntObj (tp
->enabled
));
2706 Tcl_ListObjAppendElement (interp
, list
, Tcl_NewIntObj (tp
->pass_count
));
2707 Tcl_ListObjAppendElement (interp
, list
, Tcl_NewIntObj (tp
->step_count
));
2708 Tcl_ListObjAppendElement (interp
, list
, Tcl_NewIntObj (tp
->thread
));
2709 Tcl_ListObjAppendElement (interp
, list
, Tcl_NewIntObj (tp
->hit_count
));
2711 /* Append a list of actions */
2712 action_list
= Tcl_NewListObj (0, NULL
);
2713 for (al
= tp
->actions
; al
!= NULL
; al
= al
->next
)
2715 Tcl_ListObjAppendElement (interp
, action_list
,
2716 Tcl_NewStringObj (al
->action
, -1));
2718 Tcl_ListObjAppendElement (interp
, list
, action_list
);
2720 Tcl_SetObjResult (interp
, list
);
2725 /* TclDebug (const char *fmt, ...) works just like printf() but */
2726 /* sends the output to the GDB TK debug window. */
2727 /* Not for normal use; just a convenient tool for debugging */
2729 #ifdef ANSI_PROTOTYPES
2730 TclDebug (const char *fmt
, ...)
2737 char buf
[512], *v
[2], *merge
;
2739 #ifdef ANSI_PROTOTYPES
2740 va_start (args
, fmt
);
2744 fmt
= va_arg (args
, char *);
2750 vsprintf (buf
, fmt
, args
);
2753 merge
= Tcl_Merge (2, v
);
2754 Tcl_Eval (interp
, merge
);
2759 /* Find the full pathname to a file, searching the symbol tables */
2762 gdb_find_file_command (clientData
, interp
, objc
, objv
)
2763 ClientData clientData
;
2766 Tcl_Obj
*CONST objv
[];
2768 char *filename
= NULL
;
2773 Tcl_WrongNumArgs(interp
, 1, objv
, "filename");
2777 st
= full_lookup_symtab (Tcl_GetStringFromObj (objv
[1], NULL
));
2779 filename
= st
->fullname
;
2781 if (filename
== NULL
)
2782 Tcl_SetObjResult (interp
, Tcl_NewStringObj ("", 0));
2784 Tcl_SetObjResult (interp
, Tcl_NewStringObj (filename
, -1));
2790 gdbtk_create_tracepoint (tp
)
2791 struct tracepoint
*tp
;
2793 tracepoint_notify (tp
, "create");
2797 gdbtk_delete_tracepoint (tp
)
2798 struct tracepoint
*tp
;
2800 tracepoint_notify (tp
, "delete");
2804 gdbtk_modify_tracepoint (tp
)
2805 struct tracepoint
*tp
;
2807 tracepoint_notify (tp
, "modify");
2811 tracepoint_notify(tp
, action
)
2812 struct tracepoint
*tp
;
2817 struct symtab_and_line sal
;
2820 /* We ensure that ACTION contains no special Tcl characters, so we
2822 sal
= find_pc_line (tp
->address
, 0);
2824 filename
= symtab_to_filename (sal
.symtab
);
2825 if (filename
== NULL
)
2827 sprintf (buf
, "gdbtk_tcl_tracepoint %s %d 0x%lx %d {%s}", action
, tp
->number
,
2828 (long)tp
->address
, sal
.line
, filename
, tp
->pass_count
);
2830 v
= Tcl_Eval (interp
, buf
);
2834 gdbtk_fputs (interp
->result
, gdb_stdout
);
2835 gdbtk_fputs ("\n", gdb_stdout
);
2839 /* returns -1 if not found, tracepoint # if found */
2841 tracepoint_exists (char * args
)
2843 struct tracepoint
*tp
;
2845 struct symtabs_and_lines sals
;
2849 sals
= decode_line_1 (&args
, 1, NULL
, 0, &canonical
);
2850 if (sals
.nelts
== 1)
2852 resolve_sal_pc (&sals
.sals
[0]);
2853 file
= xmalloc (strlen (sals
.sals
[0].symtab
->dirname
)
2854 + strlen (sals
.sals
[0].symtab
->filename
) + 1);
2857 strcpy (file
, sals
.sals
[0].symtab
->dirname
);
2858 strcat (file
, sals
.sals
[0].symtab
->filename
);
2860 ALL_TRACEPOINTS (tp
)
2862 if (tp
->address
== sals
.sals
[0].pc
)
2863 result
= tp
->number
;
2865 /* Why is this here? This messes up assembly traces */
2866 else if (tp
->source_file
!= NULL
2867 && strcmp (tp
->source_file
, file
) == 0
2868 && sals
.sals
[0].line
== tp
->line_number
)
2869 result
= tp
->number
;
2880 gdb_actions_command (clientData
, interp
, objc
, objv
)
2881 ClientData clientData
;
2884 Tcl_Obj
*CONST objv
[];
2886 struct tracepoint
*tp
;
2888 int nactions
, i
, len
;
2889 char *number
, *args
, *action
;
2891 struct action_line
*next
= NULL
, *temp
;
2895 Tcl_AppendResult (interp
, "wrong # args: should be: \"",
2896 Tcl_GetStringFromObj (objv
[0], NULL
),
2897 " number actions\"");
2901 args
= number
= Tcl_GetStringFromObj (objv
[1], NULL
);
2902 tp
= get_tracepoint_by_number (&args
);
2905 Tcl_AppendResult (interp
, "Tracepoint \"", number
, "\" does not exist");
2909 /* Free any existing actions */
2910 if (tp
->actions
!= NULL
)
2915 Tcl_ListObjGetElements (interp
, objv
[2], &nactions
, &actions
);
2916 for (i
= 0; i
< nactions
; i
++)
2918 temp
= xmalloc (sizeof (struct action_line
));
2920 action
= Tcl_GetStringFromObj (actions
[i
], &len
);
2921 temp
->action
= savestring (action
, len
);
2922 if (sscanf (temp
->action
, "while-stepping %d", &step_count
) !=0)
2923 tp
->step_count
= step_count
;
2940 gdb_tracepoint_exists_command (clientData
, interp
, objc
, objv
)
2941 ClientData clientData
;
2944 Tcl_Obj
*CONST objv
[];
2950 Tcl_AppendResult (interp
, "wrong # of args: should be \"",
2951 Tcl_GetStringFromObj (objv
[0], NULL
),
2952 " function:line|function|line|*addr\"");
2956 args
= Tcl_GetStringFromObj (objv
[1], NULL
);
2958 Tcl_SetObjResult (interp
, Tcl_NewIntObj (tracepoint_exists (args
)));
2962 /* Return the prompt to the interpreter */
2964 gdb_prompt_command (clientData
, interp
, objc
, objv
)
2965 ClientData clientData
;
2968 Tcl_Obj
*CONST objv
[];
2970 Tcl_SetResult (interp
, get_prompt (), TCL_VOLATILE
);
2974 /* return a list of all tracepoint numbers in interpreter */
2976 gdb_get_tracepoint_list (clientData
, interp
, objc
, objv
)
2977 ClientData clientData
;
2980 Tcl_Obj
*CONST objv
[];
2983 struct tracepoint
*tp
;
2985 list
= Tcl_NewListObj (0, NULL
);
2987 ALL_TRACEPOINTS (tp
)
2988 Tcl_ListObjAppendElement (interp
, list
, Tcl_NewIntObj (tp
->number
));
2990 Tcl_SetObjResult (interp
, list
);
2995 /* This hook is called whenever we are ready to load a symbol file so that
2996 the UI can notify the user... */
2998 gdbtk_pre_add_symbol (name
)
3003 v
[0] = "gdbtk_tcl_pre_add_symbol";
3005 merge
= Tcl_Merge (2, v
);
3006 Tcl_Eval (interp
, merge
);
3010 /* This hook is called whenever we finish loading a symbol file. */
3012 gdbtk_post_add_symbol ()
3014 Tcl_Eval (interp
, "gdbtk_tcl_post_add_symbol");
3020 gdbtk_print_frame_info (s
, line
, stopline
, noerror
)
3026 current_source_symtab
= s
;
3027 current_source_line
= line
;
3031 /* The lookup_symtab() in symtab.c doesn't work correctly */
3032 /* It will not work will full pathnames and if multiple */
3033 /* source files have the same basename, it will return */
3034 /* the first one instead of the correct one. This version */
3035 /* also always makes sure symtab->fullname is set. */
3037 static struct symtab
*
3038 full_lookup_symtab(file
)
3042 struct objfile
*objfile
;
3043 char *bfile
, *fullname
;
3044 struct partial_symtab
*pt
;
3049 /* first try a direct lookup */
3050 st
= lookup_symtab (file
);
3054 symtab_to_filename(st
);
3058 /* if the direct approach failed, try */
3059 /* looking up the basename and checking */
3060 /* all matches with the fullname */
3061 bfile
= basename (file
);
3062 ALL_SYMTABS (objfile
, st
)
3064 if (!strcmp (bfile
, basename(st
->filename
)))
3067 fullname
= symtab_to_filename (st
);
3069 fullname
= st
->fullname
;
3071 if (!strcmp (file
, fullname
))
3076 /* still no luck? look at psymtabs */
3077 ALL_PSYMTABS (objfile
, pt
)
3079 if (!strcmp (bfile
, basename(pt
->filename
)))
3081 st
= PSYMTAB_TO_SYMTAB (pt
);
3084 fullname
= symtab_to_filename (st
);
3085 if (!strcmp (file
, fullname
))
3094 /* gdb_loadfile loads a c source file into a text widget. */
3096 /* LTABLE_SIZE is the number of bytes to allocate for the */
3097 /* line table. Its size limits the maximum number of lines */
3098 /* in a file to 8 * LTABLE_SIZE. This memory is freed after */
3099 /* the file is loaded, so it is OK to make this very large. */
3100 /* Additional memory will be allocated if needed. */
3101 #define LTABLE_SIZE 20000
3104 gdb_loadfile (clientData
, interp
, objc
, objv
)
3105 ClientData clientData
;
3108 Tcl_Obj
*CONST objv
[];
3110 char *file
, *widget
, *line
, *buf
, msg
[128];
3111 int linenumbers
, ln
, anum
, lnum
, ltable_size
;
3112 Tcl_Obj
*a
[2], *b
[2], *cmd
;
3115 struct symtab
*symtab
;
3116 struct linetable_entry
*le
;
3120 Tcl_WrongNumArgs(interp
, 1, objv
, "widget filename linenumbers");
3124 widget
= Tcl_GetStringFromObj (objv
[1], NULL
);
3125 file
= Tcl_GetStringFromObj (objv
[2], NULL
);
3126 Tcl_GetBooleanFromObj (interp
, objv
[3], &linenumbers
);
3128 if ((fp
= fopen ( file
, "r" )) == NULL
)
3131 symtab
= full_lookup_symtab (file
);
3134 sprintf(msg
, "File not found");
3135 Tcl_SetStringObj ( Tcl_GetObjResult (interp
), msg
, -1);
3140 /* Source linenumbers don't appear to be in order, and a sort is */
3141 /* too slow so the fastest solution is just to allocate a huge */
3142 /* array and set the array entry for each linenumber */
3144 ltable_size
= LTABLE_SIZE
;
3145 ltable
= (char *)malloc (LTABLE_SIZE
);
3148 sprintf(msg
, "Out of memory.");
3149 Tcl_SetStringObj ( Tcl_GetObjResult (interp
), msg
, -1);
3154 memset (ltable
, 0, LTABLE_SIZE
);
3156 if (symtab
->linetable
&& symtab
->linetable
->nitems
)
3158 le
= symtab
->linetable
->item
;
3159 for (ln
= symtab
->linetable
->nitems
;ln
> 0; ln
--, le
++)
3161 lnum
= le
->line
>> 3;
3162 if (lnum
>= ltable_size
)
3165 new_ltable
= (char *)realloc (ltable
, ltable_size
*2);
3166 memset (new_ltable
+ ltable_size
, 0, ltable_size
);
3168 if (new_ltable
== NULL
)
3170 sprintf(msg
, "Out of memory.");
3171 Tcl_SetStringObj ( Tcl_GetObjResult (interp
), msg
, -1);
3176 ltable
= new_ltable
;
3178 ltable
[lnum
] |= 1 << (le
->line
% 8);
3182 /* create an object with enough space, then grab its */
3183 /* buffer and sprintf directly into it. */
3184 a
[0] = Tcl_NewStringObj (ltable
, 1024);
3185 a
[1] = Tcl_NewListObj(0,NULL
);
3187 b
[0] = Tcl_NewStringObj (ltable
,1024);
3188 b
[1] = Tcl_NewStringObj ("source_tag", -1);
3189 Tcl_IncrRefCount (b
[0]);
3190 Tcl_IncrRefCount (b
[1]);
3191 line
= b
[0]->bytes
+ 1;
3192 strcpy(b
[0]->bytes
,"\t");
3195 while (fgets (line
, 980, fp
))
3199 if (ltable
[ln
>> 3] & (1 << (ln
% 8)))
3201 sprintf (buf
,"%s insert end {-\t%d} break_tag", widget
, ln
);
3202 a
[0]->length
= strlen (buf
);
3206 sprintf (buf
,"%s insert end { \t%d} \"\"", widget
, ln
);
3207 a
[0]->length
= strlen (buf
);
3212 if (ltable
[ln
>> 3] & (1 << (ln
% 8)))
3214 sprintf (buf
,"%s insert end {-\t} break_tag", widget
);
3215 a
[0]->length
= strlen (buf
);
3219 sprintf (buf
,"%s insert end { \t} \"\"", widget
);
3220 a
[0]->length
= strlen (buf
);
3223 b
[0]->length
= strlen(b
[0]->bytes
);
3224 Tcl_SetListObj(a
[1],2,b
);
3225 cmd
= Tcl_ConcatObj(2,a
);
3226 Tcl_EvalObj (interp
, cmd
);
3227 Tcl_DecrRefCount (cmd
);
3230 Tcl_DecrRefCount (b
[0]);
3231 Tcl_DecrRefCount (b
[0]);
3232 Tcl_DecrRefCount (b
[1]);
3233 Tcl_DecrRefCount (b
[1]);
3239 /* at some point make these static in breakpoint.c and move GUI code there */
3240 extern struct breakpoint
*set_raw_breakpoint (struct symtab_and_line sal
);
3241 extern void set_breakpoint_count (int);
3242 extern int breakpoint_count
;
3244 /* set a breakpoint by source file and line number */
3245 /* flags are as follows: */
3246 /* least significant 2 bits are disposition, rest is */
3247 /* type (normally 0).
3250 bp_breakpoint, Normal breakpoint
3251 bp_hardware_breakpoint, Hardware assisted breakpoint
3254 Disposition of breakpoint. Ie: what to do after hitting it.
3257 del_at_next_stop, Delete at next stop, whether hit or not
3259 donttouch Leave it alone
3264 gdb_set_bp (clientData
, interp
, objc
, objv
)
3265 ClientData clientData
;
3268 Tcl_Obj
*CONST objv
[];
3271 struct symtab_and_line sal
;
3272 int line
, flags
, ret
;
3273 struct breakpoint
*b
;
3275 Tcl_Obj
*a
[5], *cmd
;
3279 Tcl_WrongNumArgs(interp
, 1, objv
, "filename line type");
3283 sal
.symtab
= full_lookup_symtab (Tcl_GetStringFromObj( objv
[1], NULL
));
3284 if (sal
.symtab
== NULL
)
3287 if (Tcl_GetIntFromObj( interp
, objv
[2], &line
) == TCL_ERROR
)
3290 if (Tcl_GetIntFromObj( interp
, objv
[3], &flags
) == TCL_ERROR
)
3294 sal
.pc
= find_line_pc (sal
.symtab
, sal
.line
);
3298 sal
.section
= find_pc_overlay (sal
.pc
);
3299 b
= set_raw_breakpoint (sal
);
3300 set_breakpoint_count (breakpoint_count
+ 1);
3301 b
->number
= breakpoint_count
;
3302 b
->type
= flags
>> 2;
3303 b
->disposition
= flags
& 3;
3305 /* FIXME: this won't work for duplicate basenames! */
3306 sprintf (buf
, "%s:%d", basename(Tcl_GetStringFromObj( objv
[1], NULL
)), line
);
3307 b
->addr_string
= strsave (buf
);
3309 /* now send notification command back to GUI */
3310 sprintf (buf
, "0x%x", sal
.pc
);
3311 a
[0] = Tcl_NewStringObj ("gdbtk_tcl_breakpoint create", -1);
3312 a
[1] = Tcl_NewIntObj (b
->number
);
3313 a
[2] = Tcl_NewStringObj (buf
, -1);
3315 a
[4] = Tcl_NewListObj (1,&objv
[1]);
3316 cmd
= Tcl_ConcatObj(5,a
);
3317 ret
= Tcl_EvalObj (interp
, cmd
);
3318 Tcl_DecrRefCount (cmd
);
3323 /* The whole timer idea is an easy one, but POSIX does not appear to have
3324 some sort of interval timer requirement. Consequently, we cannot rely
3325 on cygwin32 to always deliver the timer's signal. This is especially
3326 painful given that all serial I/O will block the timer right now. */
3328 gdbtk_annotate_starting ()
3330 /* TclDebug ("### STARTING ###"); */
3331 gdbtk_start_timer ();
3335 gdbtk_annotate_stopped ()
3337 /* TclDebug ("### STOPPED ###"); */
3338 gdbtk_stop_timer ();
3342 gdbtk_annotate_exited ()
3344 /* TclDebug ("### EXITED ###"); */
3345 gdbtk_stop_timer ();
3349 gdbtk_annotate_signalled ()
3351 /* TclDebug ("### SIGNALLED ###"); */
3352 gdbtk_stop_timer ();
3356 /* Come here during initialize_all_files () */
3359 _initialize_gdbtk ()
3363 /* Tell the rest of the world that Gdbtk is now set up. */
3365 init_ui_hook
= gdbtk_init
;