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"
72 #define GDBTK_PATH_SEP ";"
74 #define GDBTK_PATH_SEP ":"
77 /* Some versions (1.3.79, 1.3.81) of Linux don't support SIOCSPGRP the way
78 gdbtk wants to use it... */
83 static int No_Update
= 0;
84 static int load_in_progress
= 0;
85 static int in_fputs
= 0;
87 int gdbtk_load_hash
PARAMS ((char *, unsigned long));
88 int (*ui_load_progress_hook
) PARAMS ((char *, unsigned long));
89 void (*pre_add_symbol_hook
) PARAMS ((char *));
90 void (*post_add_symbol_hook
) PARAMS ((void));
92 char * get_prompt
PARAMS ((void));
94 static void null_routine
PARAMS ((int));
95 static void gdbtk_flush
PARAMS ((FILE *));
96 static void gdbtk_fputs
PARAMS ((const char *, FILE *));
97 static int gdbtk_query
PARAMS ((const char *, va_list));
98 static char *gdbtk_readline
PARAMS ((char *));
99 static void gdbtk_init
PARAMS ((char *));
100 static void tk_command_loop
PARAMS ((void));
101 static void gdbtk_call_command
PARAMS ((struct cmd_list_element
*, char *, int));
102 static int gdbtk_wait
PARAMS ((int, struct target_waitstatus
*));
103 static void x_event
PARAMS ((int));
104 static void gdbtk_interactive
PARAMS ((void));
105 static void cleanup_init
PARAMS ((int));
106 static void tk_command
PARAMS ((char *, int));
107 static int gdb_disassemble
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
108 static int compare_lines
PARAMS ((const PTR
, const PTR
));
109 static int gdbtk_dis_asm_read_memory
PARAMS ((bfd_vma
, bfd_byte
*, int, disassemble_info
*));
110 static int gdb_path_conv
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
111 static int gdb_stop
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
112 static int gdb_confirm_quit
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
113 static int gdb_force_quit
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
114 static int gdb_listfiles
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
115 static int gdb_listfuncs
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
116 static int call_wrapper
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
117 static int gdb_cmd
PARAMS ((ClientData
, Tcl_Interp
*, int, char *argv
[]));
118 static int gdb_immediate_command
PARAMS ((ClientData
, Tcl_Interp
*, int, char *argv
[]));
119 static int gdb_fetch_registers
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
120 static void gdbtk_readline_end
PARAMS ((void));
121 static void pc_changed
PARAMS ((void));
122 static int gdb_changed_register_list
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
123 static void register_changed_p
PARAMS ((int, void *));
124 static int gdb_get_breakpoint_list
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
125 static int gdb_get_breakpoint_info
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
126 static void breakpoint_notify
PARAMS ((struct breakpoint
*, const char *));
127 static void gdbtk_create_breakpoint
PARAMS ((struct breakpoint
*));
128 static void gdbtk_delete_breakpoint
PARAMS ((struct breakpoint
*));
129 static void gdbtk_modify_breakpoint
PARAMS ((struct breakpoint
*));
130 static int gdb_loc
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
131 static int gdb_eval
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
132 static int map_arg_registers
PARAMS ((int, char *[], void (*) (int, void *), void *));
133 static void get_register_name
PARAMS ((int, void *));
134 static int gdb_regnames
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
135 static void get_register
PARAMS ((int, void *));
136 static int gdb_trace_status
PARAMS ((ClientData
, Tcl_Interp
*, int, char *argv
[]));
137 static int gdb_target_has_execution_command
PARAMS ((ClientData
, Tcl_Interp
*, int, char *argv
[]));
138 static int gdb_load_info
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
139 void TclDebug
PARAMS ((const char *fmt
, ...));
140 static int gdb_get_vars_command
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
141 static int gdb_get_function_command
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
142 static int gdb_get_line_command
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
143 static int gdb_get_file_command
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
144 static int gdb_tracepoint_exists_command
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
145 static int gdb_get_tracepoint_info
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
146 static int gdb_actions_command
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
147 static int gdb_prompt_command
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
148 static int gdb_find_file_command
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
149 static int gdb_get_tracepoint_list
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
150 static void gdbtk_create_tracepoint
PARAMS ((struct tracepoint
*));
151 static void gdbtk_delete_tracepoint
PARAMS ((struct tracepoint
*));
152 static void gdbtk_modify_tracepoint
PARAMS ((struct tracepoint
*));
153 static void tracepoint_notify
PARAMS ((struct tracepoint
*, const char *));
154 static void gdbtk_print_frame_info
PARAMS ((struct symtab
*, int, int, int));
155 void gdbtk_pre_add_symbol
PARAMS ((char *));
156 void gdbtk_post_add_symbol
PARAMS ((void));
157 static int get_pc_register
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
158 static int gdb_loadfile
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
159 static int gdb_set_bp
PARAMS ((ClientData
, Tcl_Interp
*, int, Tcl_Obj
*CONST objv
[]));
160 static struct symtab
*full_lookup_symtab
PARAMS ((char *file
));
161 static int gdb_get_mem
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
163 /* Handle for TCL interpreter */
164 static Tcl_Interp
*interp
= NULL
;
166 static int gdbtk_timer_going
= 0;
167 static void gdbtk_start_timer
PARAMS ((void));
168 static void gdbtk_stop_timer
PARAMS ((void));
170 /* This variable is true when the inferior is running. Although it's
171 possible to disable most input from widgets and thus prevent
172 attempts to do anything while the inferior is running, any commands
173 that get through - even a simple memory read - are Very Bad, and
174 may cause GDB to crash or behave strangely. So, this variable
175 provides an extra layer of defense. */
177 static int running_now
;
179 /* This variable determines where memory used for disassembly is read from.
180 If > 0, then disassembly comes from the exec file rather than the
181 target (which might be at the other end of a slow serial link). If
182 == 0 then disassembly comes from target. If < 0 disassembly is
183 automatically switched to the target if it's an inferior process,
184 otherwise the exec file is used. */
186 static int disassemble_from_exec
= -1;
190 /* Supply malloc calls for tcl/tk. We do not want to do this on
191 Windows, because Tcl_Alloc is probably in a DLL which will not call
192 the mmalloc routines. */
198 return xmalloc (size
);
202 Tcl_Realloc (ptr
, size
)
206 return xrealloc (ptr
, size
);
216 #endif /* ! _WIN32 */
226 /* On Windows, if we hold a file open, other programs can't write to
227 it. In particular, we don't want to hold the executable open,
228 because it will mean that people have to get out of the debugging
229 session in order to remake their program. So we close it, although
230 this will cost us if and when we need to reopen it. */
240 bfd_cache_close (o
->obfd
);
243 if (exec_bfd
!= NULL
)
244 bfd_cache_close (exec_bfd
);
249 /* The following routines deal with stdout/stderr data, which is created by
250 {f}printf_{un}filtered and friends. gdbtk_fputs and gdbtk_flush are the
251 lowest level of these routines and capture all output from the rest of GDB.
252 Normally they present their data to tcl via callbacks to the following tcl
253 routines: gdbtk_tcl_fputs, gdbtk_tcl_fputs_error, and gdbtk_flush. These
254 in turn call tk routines to update the display.
256 Under some circumstances, you may want to collect the output so that it can
257 be returned as the value of a tcl procedure. This can be done by
258 surrounding the output routines with calls to start_saving_output and
259 finish_saving_output. The saved data can then be retrieved with
260 get_saved_output (but this must be done before the call to
261 finish_saving_output). */
263 /* Dynamic string for output. */
265 static Tcl_DString
*result_ptr
;
267 /* Dynamic string for stderr. This is only used if result_ptr is
270 static Tcl_DString
*error_string_ptr
;
277 /* Force immediate screen update */
279 Tcl_VarEval (interp
, "gdbtk_tcl_flush", NULL
);
284 gdbtk_fputs (ptr
, stream
)
288 char *merge
[2], *command
;
292 Tcl_DStringAppend (result_ptr
, (char *) ptr
, -1);
293 else if (error_string_ptr
!= NULL
&& stream
== gdb_stderr
)
294 Tcl_DStringAppend (error_string_ptr
, (char *) ptr
, -1);
297 merge
[0] = "gdbtk_tcl_fputs";
298 merge
[1] = (char *)ptr
;
299 command
= Tcl_Merge (2, merge
);
300 Tcl_Eval (interp
, command
);
307 gdbtk_query (query
, args
)
311 char buf
[200], *merge
[2];
315 vsprintf (buf
, query
, args
);
316 merge
[0] = "gdbtk_tcl_query";
318 command
= Tcl_Merge (2, merge
);
319 Tcl_Eval (interp
, command
);
322 val
= atol (interp
->result
);
328 #ifdef ANSI_PROTOTYPES
329 gdbtk_readline_begin (char *format
, ...)
331 gdbtk_readline_begin (va_alist
)
336 char buf
[200], *merge
[2];
339 #ifdef ANSI_PROTOTYPES
340 va_start (args
, format
);
344 format
= va_arg (args
, char *);
347 vsprintf (buf
, format
, args
);
348 merge
[0] = "gdbtk_tcl_readline_begin";
350 command
= Tcl_Merge (2, merge
);
351 Tcl_Eval (interp
, command
);
356 gdbtk_readline (prompt
)
367 merge
[0] = "gdbtk_tcl_readline";
369 command
= Tcl_Merge (2, merge
);
370 result
= Tcl_Eval (interp
, command
);
372 if (result
== TCL_OK
)
374 return (strdup (interp
-> result
));
378 gdbtk_fputs (interp
-> result
, gdb_stdout
);
379 gdbtk_fputs ("\n", gdb_stdout
);
385 gdbtk_readline_end ()
387 Tcl_Eval (interp
, "gdbtk_tcl_readline_end");
393 Tcl_Eval (interp
, "gdbtk_pc_changed");
398 #ifdef ANSI_PROTOTYPES
399 dsprintf_append_element (Tcl_DString
*dsp
, char *format
, ...)
401 dsprintf_append_element (va_alist
)
408 #ifdef ANSI_PROTOTYPES
409 va_start (args
, format
);
415 dsp
= va_arg (args
, Tcl_DString
*);
416 format
= va_arg (args
, char *);
419 vsprintf (buf
, format
, args
);
421 Tcl_DStringAppendElement (dsp
, buf
);
425 gdb_path_conv (clientData
, interp
, argc
, argv
)
426 ClientData clientData
;
432 char pathname
[256], *ptr
;
434 error ("wrong # args");
435 cygwin32_conv_to_full_win32_path (argv
[1], pathname
);
436 for (ptr
= pathname
; *ptr
; ptr
++)
442 char *pathname
= argv
[1];
444 Tcl_DStringAppend (result_ptr
, pathname
, strlen(pathname
));
449 gdb_get_breakpoint_list (clientData
, interp
, argc
, argv
)
450 ClientData clientData
;
455 struct breakpoint
*b
;
456 extern struct breakpoint
*breakpoint_chain
;
459 error ("wrong # args");
461 for (b
= breakpoint_chain
; b
; b
= b
->next
)
462 if (b
->type
== bp_breakpoint
)
463 dsprintf_append_element (result_ptr
, "%d", b
->number
);
469 gdb_get_breakpoint_info (clientData
, interp
, argc
, argv
)
470 ClientData clientData
;
475 struct symtab_and_line sal
;
476 static char *bptypes
[] = {"breakpoint", "hardware breakpoint", "until",
477 "finish", "watchpoint", "hardware watchpoint",
478 "read watchpoint", "access watchpoint",
479 "longjmp", "longjmp resume", "step resume",
480 "through sigtramp", "watchpoint scope",
482 static char *bpdisp
[] = {"delete", "delstop", "disable", "donttouch"};
483 struct command_line
*cmd
;
485 struct breakpoint
*b
;
486 extern struct breakpoint
*breakpoint_chain
;
487 char *funcname
, *fname
, *filename
;
490 error ("wrong # args");
492 bpnum
= atoi (argv
[1]);
494 for (b
= breakpoint_chain
; b
; b
= b
->next
)
495 if (b
->number
== bpnum
)
498 if (!b
|| b
->type
!= bp_breakpoint
)
499 error ("Breakpoint #%d does not exist", bpnum
);
501 sal
= find_pc_line (b
->address
, 0);
503 filename
= symtab_to_filename (sal
.symtab
);
504 if (filename
== NULL
)
506 Tcl_DStringAppendElement (result_ptr
, filename
);
508 find_pc_partial_function (b
->address
, &funcname
, NULL
, NULL
);
509 fname
= cplus_demangle (funcname
, 0);
512 Tcl_DStringAppendElement (result_ptr
, fname
);
516 Tcl_DStringAppendElement (result_ptr
, funcname
);
517 dsprintf_append_element (result_ptr
, "%d", b
->line_number
);
518 dsprintf_append_element (result_ptr
, "0x%lx", b
->address
);
519 Tcl_DStringAppendElement (result_ptr
, bptypes
[b
->type
]);
520 Tcl_DStringAppendElement (result_ptr
, b
->enable
== enabled
? "1" : "0");
521 Tcl_DStringAppendElement (result_ptr
, bpdisp
[b
->disposition
]);
522 dsprintf_append_element (result_ptr
, "%d", b
->ignore_count
);
524 Tcl_DStringStartSublist (result_ptr
);
525 for (cmd
= b
->commands
; cmd
; cmd
= cmd
->next
)
526 Tcl_DStringAppendElement (result_ptr
, cmd
->line
);
527 Tcl_DStringEndSublist (result_ptr
);
529 Tcl_DStringAppendElement (result_ptr
, b
->cond_string
);
531 dsprintf_append_element (result_ptr
, "%d", b
->thread
);
532 dsprintf_append_element (result_ptr
, "%d", b
->hit_count
);
538 breakpoint_notify(b
, action
)
539 struct breakpoint
*b
;
544 struct symtab_and_line sal
;
547 if (b
->type
!= bp_breakpoint
)
550 /* We ensure that ACTION contains no special Tcl characters, so we
552 sal
= find_pc_line (b
->address
, 0);
553 filename
= symtab_to_filename (sal
.symtab
);
554 if (filename
== NULL
)
557 sprintf (buf
, "gdbtk_tcl_breakpoint %s %d 0x%lx %d {%s}", action
, b
->number
,
558 (long)b
->address
, b
->line_number
, filename
);
560 v
= Tcl_Eval (interp
, buf
);
564 gdbtk_fputs (interp
->result
, gdb_stdout
);
565 gdbtk_fputs ("\n", gdb_stdout
);
570 gdbtk_create_breakpoint(b
)
571 struct breakpoint
*b
;
573 breakpoint_notify (b
, "create");
577 gdbtk_delete_breakpoint(b
)
578 struct breakpoint
*b
;
580 breakpoint_notify (b
, "delete");
584 gdbtk_modify_breakpoint(b
)
585 struct breakpoint
*b
;
587 breakpoint_notify (b
, "modify");
590 /* This implements the TCL command `gdb_loc', which returns a list */
591 /* consisting of the following: */
592 /* basename, function name, filename, line number, address, current pc */
595 gdb_loc (clientData
, interp
, argc
, argv
)
596 ClientData clientData
;
602 struct symtab_and_line sal
;
603 char *funcname
, *fname
;
606 if (!have_full_symbols () && !have_partial_symbols ())
608 Tcl_SetResult (interp
, "No symbol table is loaded", TCL_STATIC
);
614 if (selected_frame
&& (selected_frame
->pc
!= stop_pc
))
616 /* Note - this next line is not correct on all architectures. */
617 /* For a graphical debugged we really want to highlight the */
618 /* assembly line that called the next function on the stack. */
619 /* Many architectures have the next instruction saved as the */
620 /* pc on the stack, so what happens is the next instruction is hughlighted. */
622 pc
= selected_frame
->pc
;
623 sal
= find_pc_line (selected_frame
->pc
,
624 selected_frame
->next
!= NULL
625 && !selected_frame
->next
->signal_handler_caller
626 && !frame_in_dummy (selected_frame
->next
));
631 sal
= find_pc_line (stop_pc
, 0);
636 struct symtabs_and_lines sals
;
639 sals
= decode_line_spec (argv
[1], 1);
646 error ("Ambiguous line spec");
651 error ("wrong # args");
654 Tcl_DStringAppendElement (result_ptr
, sal
.symtab
->filename
);
656 Tcl_DStringAppendElement (result_ptr
, "");
658 find_pc_partial_function (pc
, &funcname
, NULL
, NULL
);
659 fname
= cplus_demangle (funcname
, 0);
662 Tcl_DStringAppendElement (result_ptr
, fname
);
666 Tcl_DStringAppendElement (result_ptr
, funcname
);
667 filename
= symtab_to_filename (sal
.symtab
);
668 if (filename
== NULL
)
671 Tcl_DStringAppendElement (result_ptr
, filename
);
672 dsprintf_append_element (result_ptr
, "%d", sal
.line
); /* line number */
673 dsprintf_append_element (result_ptr
, "0x%s", paddr_nz(pc
)); /* PC in current frame */
674 dsprintf_append_element (result_ptr
, "0x%s", paddr_nz(stop_pc
)); /* Real PC */
678 /* This implements the TCL command `gdb_eval'. */
681 gdb_eval (clientData
, interp
, argc
, argv
)
682 ClientData clientData
;
687 struct expression
*expr
;
688 struct cleanup
*old_chain
;
692 error ("wrong # args");
694 expr
= parse_expression (argv
[1]);
696 old_chain
= make_cleanup (free_current_contents
, &expr
);
698 val
= evaluate_expression (expr
);
700 val_print (VALUE_TYPE (val
), VALUE_CONTENTS (val
), VALUE_ADDRESS (val
),
701 gdb_stdout
, 0, 0, 0, 0);
703 do_cleanups (old_chain
);
708 /* gdb_get_mem addr form size num aschar*/
709 /* dump a block of memory */
710 /* addr: address of data to dump */
711 /* form: a char indicating format */
712 /* size: size of each element; 1,2,4, or 8 bytes*/
713 /* num: the number of bytes to read */
714 /* acshar: an optional ascii character to use in ASCII dump */
715 /* returns a list of elements followed by an optional */
719 gdb_get_mem (clientData
, interp
, argc
, argv
)
720 ClientData clientData
;
725 int size
, asize
, i
, j
, bc
;
727 int nbytes
, rnum
, bpr
;
728 char format
, c
, *ptr
, buff
[128], aschar
, *mbuf
, *mptr
, *cptr
, *bptr
;
729 struct type
*val_type
;
731 if (argc
< 6 || argc
> 7)
733 interp
->result
= "addr format size bytes bytes_per_row ?ascii_char?";
737 size
= (int)strtoul(argv
[3],(char **)NULL
,0);
738 nbytes
= (int)strtoul(argv
[4],(char **)NULL
,0);
739 bpr
= (int)strtoul(argv
[5],(char **)NULL
,0);
740 if (nbytes
<= 0 || bpr
<= 0 || size
<= 0)
742 interp
->result
= "Invalid number of bytes.";
746 addr
= (CORE_ADDR
)strtoul(argv
[1],(char **)NULL
,0);
748 mbuf
= (char *)malloc (nbytes
+32);
751 interp
->result
= "Out of memory.";
754 memset (mbuf
, 0, nbytes
+32);
757 rnum
= target_read_memory_partial (addr
, mbuf
, nbytes
, NULL
);
766 val_type
= builtin_type_char
;
770 val_type
= builtin_type_short
;
774 val_type
= builtin_type_int
;
778 val_type
= builtin_type_long_long
;
782 val_type
= builtin_type_char
;
786 bc
= 0; /* count of bytes in a row */
787 buff
[0] = '"'; /* buffer for ascii dump */
788 bptr
= &buff
[1]; /* pointer for ascii dump */
790 for (i
=0; i
< nbytes
; i
+= size
)
794 fputs_unfiltered ("N/A ", gdb_stdout
);
796 for ( j
= 0; j
< size
; j
++)
801 print_scalar_formatted (mptr
, val_type
, format
, asize
, gdb_stdout
);
802 fputs_unfiltered (" ", gdb_stdout
);
805 for ( j
= 0; j
< size
; j
++)
808 if (c
< 32 || c
> 126)
820 if (aschar
&& (bc
>= bpr
))
822 /* end of row. print it and reset variables */
827 fputs_unfiltered (buff
, gdb_stdout
);
837 map_arg_registers (argc
, argv
, func
, argp
)
840 void (*func
) PARAMS ((int regnum
, void *argp
));
845 /* Note that the test for a valid register must include checking the
846 reg_names array because NUM_REGS may be allocated for the union of the
847 register sets within a family of related processors. In this case, the
848 trailing entries of reg_names will change depending upon the particular
849 processor being debugged. */
851 if (argc
== 0) /* No args, just do all the regs */
855 && reg_names
[regnum
] != NULL
856 && *reg_names
[regnum
] != '\000';
863 /* Else, list of register #s, just do listed regs */
864 for (; argc
> 0; argc
--, argv
++)
866 regnum
= atoi (*argv
);
870 && reg_names
[regnum
] != NULL
871 && *reg_names
[regnum
] != '\000')
874 error ("bad register number");
881 get_register_name (regnum
, argp
)
883 void *argp
; /* Ignored */
885 Tcl_DStringAppendElement (result_ptr
, reg_names
[regnum
]);
888 /* This implements the TCL command `gdb_regnames', which returns a list of
889 all of the register names. */
892 gdb_regnames (clientData
, interp
, argc
, argv
)
893 ClientData clientData
;
901 return map_arg_registers (argc
, argv
, get_register_name
, NULL
);
904 #ifndef REGISTER_CONVERTIBLE
905 #define REGISTER_CONVERTIBLE(x) (0 != 0)
908 #ifndef REGISTER_CONVERT_TO_VIRTUAL
909 #define REGISTER_CONVERT_TO_VIRTUAL(x, y, z, a)
912 #ifndef INVALID_FLOAT
913 #define INVALID_FLOAT(x, y) (0 != 0)
917 get_register (regnum
, fp
)
921 char raw_buffer
[MAX_REGISTER_RAW_SIZE
];
922 char virtual_buffer
[MAX_REGISTER_VIRTUAL_SIZE
];
923 int format
= (int)fp
;
928 if (read_relative_register_raw_bytes (regnum
, raw_buffer
))
930 Tcl_DStringAppendElement (result_ptr
, "Optimized out");
934 /* Convert raw data to virtual format if necessary. */
936 if (REGISTER_CONVERTIBLE (regnum
))
938 REGISTER_CONVERT_TO_VIRTUAL (regnum
, REGISTER_VIRTUAL_TYPE (regnum
),
939 raw_buffer
, virtual_buffer
);
942 memcpy (virtual_buffer
, raw_buffer
, REGISTER_VIRTUAL_SIZE (regnum
));
947 printf_filtered ("0x");
948 for (j
= 0; j
< REGISTER_RAW_SIZE (regnum
); j
++)
950 register int idx
= TARGET_BYTE_ORDER
== BIG_ENDIAN
? j
951 : REGISTER_RAW_SIZE (regnum
) - 1 - j
;
952 printf_filtered ("%02x", (unsigned char)raw_buffer
[idx
]);
956 val_print (REGISTER_VIRTUAL_TYPE (regnum
), virtual_buffer
, 0,
957 gdb_stdout
, format
, 1, 0, Val_pretty_default
);
959 Tcl_DStringAppend (result_ptr
, " ", -1);
963 get_pc_register (clientData
, interp
, argc
, argv
)
964 ClientData clientData
;
969 sprintf(interp
->result
,"0x%llx",(long long)read_register(PC_REGNUM
));
974 gdb_fetch_registers (clientData
, interp
, argc
, argv
)
975 ClientData clientData
;
983 error ("wrong # args");
989 return map_arg_registers (argc
, argv
, get_register
, (void *) format
);
992 /* This contains the previous values of the registers, since the last call to
993 gdb_changed_register_list. */
995 static char old_regs
[REGISTER_BYTES
];
998 register_changed_p (regnum
, argp
)
1000 void *argp
; /* Ignored */
1002 char raw_buffer
[MAX_REGISTER_RAW_SIZE
];
1004 if (read_relative_register_raw_bytes (regnum
, raw_buffer
))
1007 if (memcmp (&old_regs
[REGISTER_BYTE (regnum
)], raw_buffer
,
1008 REGISTER_RAW_SIZE (regnum
)) == 0)
1011 /* Found a changed register. Save new value and return its number. */
1013 memcpy (&old_regs
[REGISTER_BYTE (regnum
)], raw_buffer
,
1014 REGISTER_RAW_SIZE (regnum
));
1016 dsprintf_append_element (result_ptr
, "%d", regnum
);
1020 gdb_changed_register_list (clientData
, interp
, argc
, argv
)
1021 ClientData clientData
;
1029 return map_arg_registers (argc
, argv
, register_changed_p
, NULL
);
1032 /* This implements the tcl command "gdb_immediate", which does exactly
1033 the same thing as gdb_cmd, except NONE of its outut is buffered. */
1034 /* This will also ALWAYS cause the busy,update, and idle hooks to be
1035 called, contrasted with gdb_cmd, which NEVER calls them. */
1037 gdb_immediate_command (clientData
, interp
, argc
, argv
)
1038 ClientData clientData
;
1043 Tcl_DString
*save_ptr
= NULL
;
1046 error ("wrong # args");
1048 if (running_now
|| load_in_progress
)
1053 Tcl_DStringAppend (result_ptr
, "", -1);
1054 save_ptr
= result_ptr
;
1057 execute_command (argv
[1], 1);
1059 bpstat_do_actions (&stop_bpstat
);
1061 result_ptr
= save_ptr
;
1066 /* This implements the TCL command `gdb_cmd', which sends its argument into
1067 the GDB command scanner. */
1068 /* This command will never cause the update, idle and busy hooks to be called
1071 gdb_cmd (clientData
, interp
, argc
, argv
)
1072 ClientData clientData
;
1077 Tcl_DString
*save_ptr
= NULL
;
1080 error ("wrong # args");
1082 if (running_now
|| load_in_progress
)
1087 /* for the load instruction (and possibly others later) we
1088 set result_ptr to NULL so gdbtk_fputs() will not buffer
1089 all the data until the command is finished. */
1091 if (strncmp ("load ", argv
[1], 5) == 0
1092 || strncmp ("while ", argv
[1], 6) == 0)
1094 Tcl_DStringAppend (result_ptr
, "", -1);
1095 save_ptr
= result_ptr
;
1097 load_in_progress
= 1;
1098 gdbtk_start_timer ();
1101 execute_command (argv
[1], 1);
1103 if (load_in_progress
)
1105 gdbtk_stop_timer ();
1106 load_in_progress
= 0;
1109 bpstat_do_actions (&stop_bpstat
);
1112 result_ptr
= save_ptr
;
1117 /* Client of call_wrapper - this routine performs the actual call to
1118 the client function. */
1120 struct wrapped_call_args
1131 struct wrapped_call_args
*args
;
1133 args
->val
= (*args
->func
) (args
->func
, args
->interp
, args
->argc
, args
->argv
);
1137 /* This routine acts as a top-level for all GDB code called by tcl/Tk. It
1138 handles cleanups, and calls to return_to_top_level (usually via error).
1139 This is necessary in order to prevent a longjmp out of the bowels of Tk,
1140 possibly leaving things in a bad state. Since this routine can be called
1141 recursively, it needs to save and restore the contents of the jmp_buf as
1145 call_wrapper (clientData
, interp
, argc
, argv
)
1146 ClientData clientData
;
1151 struct wrapped_call_args wrapped_args
;
1152 Tcl_DString result
, *old_result_ptr
;
1153 Tcl_DString error_string
, *old_error_string_ptr
;
1155 Tcl_DStringInit (&result
);
1156 old_result_ptr
= result_ptr
;
1157 result_ptr
= &result
;
1159 Tcl_DStringInit (&error_string
);
1160 old_error_string_ptr
= error_string_ptr
;
1161 error_string_ptr
= &error_string
;
1163 wrapped_args
.func
= (Tcl_CmdProc
*)clientData
;
1164 wrapped_args
.interp
= interp
;
1165 wrapped_args
.argc
= argc
;
1166 wrapped_args
.argv
= argv
;
1167 wrapped_args
.val
= 0;
1169 if (!catch_errors (wrapped_call
, &wrapped_args
, "", RETURN_MASK_ALL
))
1171 wrapped_args
.val
= TCL_ERROR
; /* Flag an error for TCL */
1173 /* Make sure the timer interrupts are turned off. */
1174 if (gdbtk_timer_going
)
1175 gdbtk_stop_timer ();
1177 gdb_flush (gdb_stderr
); /* Flush error output */
1178 gdb_flush (gdb_stdout
); /* Sometimes error output comes here as well */
1180 /* In case of an error, we may need to force the GUI into idle
1181 mode because gdbtk_call_command may have bombed out while in
1182 the command routine. */
1185 Tcl_Eval (interp
, "gdbtk_tcl_idle");
1188 /* do not suppress any errors -- a remote target could have errored */
1189 load_in_progress
= 0;
1191 if (Tcl_DStringLength (&error_string
) == 0)
1193 Tcl_DStringResult (interp
, &result
);
1194 Tcl_DStringFree (&error_string
);
1196 else if (Tcl_DStringLength (&result
) == 0)
1198 Tcl_DStringResult (interp
, &error_string
);
1199 Tcl_DStringFree (&result
);
1200 Tcl_DStringFree (&error_string
);
1204 Tcl_ResetResult (interp
);
1205 Tcl_AppendResult (interp
, Tcl_DStringValue (&result
),
1206 Tcl_DStringValue (&error_string
), (char *) NULL
);
1207 Tcl_DStringFree (&result
);
1208 Tcl_DStringFree (&error_string
);
1211 result_ptr
= old_result_ptr
;
1212 error_string_ptr
= old_error_string_ptr
;
1218 return wrapped_args
.val
;
1222 comp_files (file1
, file2
)
1223 const char *file1
[], *file2
[];
1225 return strcmp(*file1
,*file2
);
1229 gdb_listfiles (clientData
, interp
, objc
, objv
)
1230 ClientData clientData
;
1233 Tcl_Obj
*CONST objv
[];
1235 struct objfile
*objfile
;
1236 struct partial_symtab
*psymtab
;
1237 struct symtab
*symtab
;
1238 char *lastfile
, *pathname
, **files
;
1240 int i
, numfiles
= 0, len
= 0;
1244 files
= (char **) xmalloc (sizeof (char *) * files_size
);
1248 Tcl_WrongNumArgs (interp
, 1, objv
, "Usage: gdb_listfiles ?pathname?");
1252 pathname
= Tcl_GetStringFromObj (objv
[1], &len
);
1254 mylist
= Tcl_NewListObj (0, NULL
);
1256 ALL_PSYMTABS (objfile
, psymtab
)
1258 if (numfiles
== files_size
)
1260 files_size
= files_size
* 2;
1261 files
= (char **) xrealloc (files
, sizeof (char *) * files_size
);
1265 if (psymtab
->filename
)
1266 files
[numfiles
++] = basename(psymtab
->filename
);
1268 else if (!strcmp(psymtab
->filename
,basename(psymtab
->filename
))
1269 || !strncmp(pathname
,psymtab
->filename
,len
))
1270 if (psymtab
->filename
)
1271 files
[numfiles
++] = basename(psymtab
->filename
);
1274 ALL_SYMTABS (objfile
, symtab
)
1276 if (numfiles
== files_size
)
1278 files_size
= files_size
* 2;
1279 files
= (char **) xrealloc (files
, sizeof (char *) * files_size
);
1283 if (symtab
->filename
)
1284 files
[numfiles
++] = basename(symtab
->filename
);
1286 else if (!strcmp(symtab
->filename
,basename(symtab
->filename
))
1287 || !strncmp(pathname
,symtab
->filename
,len
))
1288 if (symtab
->filename
)
1289 files
[numfiles
++] = basename(symtab
->filename
);
1292 qsort (files
, numfiles
, sizeof(char *), comp_files
);
1295 for (i
= 0; i
< numfiles
; i
++)
1297 if (strcmp(files
[i
],lastfile
))
1298 Tcl_ListObjAppendElement (interp
, mylist
, Tcl_NewStringObj(files
[i
], -1));
1299 lastfile
= files
[i
];
1301 Tcl_SetObjResult (interp
, mylist
);
1307 gdb_listfuncs (clientData
, interp
, argc
, argv
)
1308 ClientData clientData
;
1313 struct symtab
*symtab
;
1314 struct blockvector
*bv
;
1321 error ("wrong # args");
1323 symtab
= full_lookup_symtab (argv
[1]);
1325 error ("No such file");
1327 bv
= BLOCKVECTOR (symtab
);
1328 for (i
= GLOBAL_BLOCK
; i
<= STATIC_BLOCK
; i
++)
1330 b
= BLOCKVECTOR_BLOCK (bv
, i
);
1331 /* Skip the sort if this block is always sorted. */
1332 if (!BLOCK_SHOULD_SORT (b
))
1333 sort_block_syms (b
);
1334 for (j
= 0; j
< BLOCK_NSYMS (b
); j
++)
1336 sym
= BLOCK_SYM (b
, j
);
1337 if (SYMBOL_CLASS (sym
) == LOC_BLOCK
)
1340 char *name
= cplus_demangle (SYMBOL_NAME(sym
), 0);
1343 sprintf (buf
,"{%s} 1", name
);
1346 sprintf (buf
,"{%s} 0", SYMBOL_NAME(sym
));
1347 Tcl_DStringAppendElement (result_ptr
, buf
);
1355 target_stop_wrapper (args
)
1363 gdb_stop (clientData
, interp
, argc
, argv
)
1364 ClientData clientData
;
1371 catch_errors (target_stop_wrapper
, NULL
, "",
1375 quit_flag
= 1; /* hope something sees this */
1380 /* Prepare to accept a new executable file. This is called when we
1381 want to clear away everything we know about the old file, without
1382 asking the user. The Tcl code will have already asked the user if
1383 necessary. After this is called, we should be able to run the
1384 `file' command without getting any questions. */
1387 gdb_clear_file (clientData
, interp
, argc
, argv
)
1388 ClientData clientData
;
1393 if (inferior_pid
!= 0 && target_has_execution
)
1396 target_detach (NULL
, 0);
1401 if (target_has_execution
)
1404 symbol_file_command (NULL
, 0);
1406 /* gdb_loc refers to stop_pc, but nothing seems to clear it, so we
1407 clear it here. FIXME: This seems like an abstraction violation
1414 /* Ask the user to confirm an exit request. */
1417 gdb_confirm_quit (clientData
, interp
, argc
, argv
)
1418 ClientData clientData
;
1425 ret
= quit_confirm ();
1426 Tcl_DStringAppendElement (result_ptr
, ret
? "1" : "0");
1430 /* Quit without asking for confirmation. */
1433 gdb_force_quit (clientData
, interp
, argc
, argv
)
1434 ClientData clientData
;
1439 quit_force ((char *) NULL
, 1);
1443 /* This implements the TCL command `gdb_disassemble'. */
1446 gdbtk_dis_asm_read_memory (memaddr
, myaddr
, len
, info
)
1450 disassemble_info
*info
;
1452 extern struct target_ops exec_ops
;
1456 res
= xfer_memory (memaddr
, myaddr
, len
, 0, &exec_ops
);
1467 /* We need a different sort of line table from the normal one cuz we can't
1468 depend upon implicit line-end pc's for lines. This is because of the
1469 reordering we are about to do. */
1471 struct my_line_entry
{
1478 compare_lines (mle1p
, mle2p
)
1482 struct my_line_entry
*mle1
, *mle2
;
1485 mle1
= (struct my_line_entry
*) mle1p
;
1486 mle2
= (struct my_line_entry
*) mle2p
;
1488 val
= mle1
->line
- mle2
->line
;
1493 return mle1
->start_pc
- mle2
->start_pc
;
1497 gdb_disassemble (clientData
, interp
, argc
, argv
)
1498 ClientData clientData
;
1503 CORE_ADDR pc
, low
, high
;
1504 int mixed_source_and_assembly
;
1505 static disassemble_info di
;
1506 static int di_initialized
;
1508 if (! di_initialized
)
1510 INIT_DISASSEMBLE_INFO_NO_ARCH (di
, gdb_stdout
,
1511 (fprintf_ftype
) fprintf_unfiltered
);
1512 di
.flavour
= bfd_target_unknown_flavour
;
1513 di
.memory_error_func
= dis_asm_memory_error
;
1514 di
.print_address_func
= dis_asm_print_address
;
1518 di
.mach
= tm_print_insn_info
.mach
;
1519 if (TARGET_BYTE_ORDER
== BIG_ENDIAN
)
1520 di
.endian
= BFD_ENDIAN_BIG
;
1522 di
.endian
= BFD_ENDIAN_LITTLE
;
1524 if (argc
!= 3 && argc
!= 4)
1525 error ("wrong # args");
1527 if (strcmp (argv
[1], "source") == 0)
1528 mixed_source_and_assembly
= 1;
1529 else if (strcmp (argv
[1], "nosource") == 0)
1530 mixed_source_and_assembly
= 0;
1532 error ("First arg must be 'source' or 'nosource'");
1534 low
= parse_and_eval_address (argv
[2]);
1538 if (find_pc_partial_function (low
, NULL
, &low
, &high
) == 0)
1539 error ("No function contains specified address");
1542 high
= parse_and_eval_address (argv
[3]);
1544 /* If disassemble_from_exec == -1, then we use the following heuristic to
1545 determine whether or not to do disassembly from target memory or from the
1548 If we're debugging a local process, read target memory, instead of the
1549 exec file. This makes disassembly of functions in shared libs work
1552 Else, we're debugging a remote process, and should disassemble from the
1553 exec file for speed. However, this is no good if the target modifies its
1554 code (for relocation, or whatever).
1557 if (disassemble_from_exec
== -1)
1558 if (strcmp (target_shortname
, "child") == 0
1559 || strcmp (target_shortname
, "procfs") == 0
1560 || strcmp (target_shortname
, "vxprocess") == 0)
1561 disassemble_from_exec
= 0; /* It's a child process, read inferior mem */
1563 disassemble_from_exec
= 1; /* It's remote, read the exec file */
1565 if (disassemble_from_exec
)
1566 di
.read_memory_func
= gdbtk_dis_asm_read_memory
;
1568 di
.read_memory_func
= dis_asm_read_memory
;
1570 /* If just doing straight assembly, all we need to do is disassemble
1571 everything between low and high. If doing mixed source/assembly, we've
1572 got a totally different path to follow. */
1574 if (mixed_source_and_assembly
)
1575 { /* Come here for mixed source/assembly */
1576 /* The idea here is to present a source-O-centric view of a function to
1577 the user. This means that things are presented in source order, with
1578 (possibly) out of order assembly immediately following. */
1579 struct symtab
*symtab
;
1580 struct linetable_entry
*le
;
1583 struct my_line_entry
*mle
;
1584 struct symtab_and_line sal
;
1589 symtab
= find_pc_symtab (low
); /* Assume symtab is valid for whole PC range */
1594 /* First, convert the linetable to a bunch of my_line_entry's. */
1596 le
= symtab
->linetable
->item
;
1597 nlines
= symtab
->linetable
->nitems
;
1602 mle
= (struct my_line_entry
*) alloca (nlines
* sizeof (struct my_line_entry
));
1606 /* Copy linetable entries for this function into our data structure, creating
1607 end_pc's and setting out_of_order as appropriate. */
1609 /* First, skip all the preceding functions. */
1611 for (i
= 0; i
< nlines
- 1 && le
[i
].pc
< low
; i
++) ;
1613 /* Now, copy all entries before the end of this function. */
1616 for (; i
< nlines
- 1 && le
[i
].pc
< high
; i
++)
1618 if (le
[i
].line
== le
[i
+ 1].line
1619 && le
[i
].pc
== le
[i
+ 1].pc
)
1620 continue; /* Ignore duplicates */
1622 mle
[newlines
].line
= le
[i
].line
;
1623 if (le
[i
].line
> le
[i
+ 1].line
)
1625 mle
[newlines
].start_pc
= le
[i
].pc
;
1626 mle
[newlines
].end_pc
= le
[i
+ 1].pc
;
1630 /* If we're on the last line, and it's part of the function, then we need to
1631 get the end pc in a special way. */
1636 mle
[newlines
].line
= le
[i
].line
;
1637 mle
[newlines
].start_pc
= le
[i
].pc
;
1638 sal
= find_pc_line (le
[i
].pc
, 0);
1639 mle
[newlines
].end_pc
= sal
.end
;
1643 /* Now, sort mle by line #s (and, then by addresses within lines). */
1646 qsort (mle
, newlines
, sizeof (struct my_line_entry
), compare_lines
);
1648 /* Now, for each line entry, emit the specified lines (unless they have been
1649 emitted before), followed by the assembly code for that line. */
1651 next_line
= 0; /* Force out first line */
1652 for (i
= 0; i
< newlines
; i
++)
1654 /* Print out everything from next_line to the current line. */
1656 if (mle
[i
].line
>= next_line
)
1659 print_source_lines (symtab
, next_line
, mle
[i
].line
+ 1, 0);
1661 print_source_lines (symtab
, mle
[i
].line
, mle
[i
].line
+ 1, 0);
1663 next_line
= mle
[i
].line
+ 1;
1666 for (pc
= mle
[i
].start_pc
; pc
< mle
[i
].end_pc
; )
1669 fputs_unfiltered (" ", gdb_stdout
);
1670 print_address (pc
, gdb_stdout
);
1671 fputs_unfiltered (":\t ", gdb_stdout
);
1672 pc
+= (*tm_print_insn
) (pc
, &di
);
1673 fputs_unfiltered ("\n", gdb_stdout
);
1680 for (pc
= low
; pc
< high
; )
1683 fputs_unfiltered (" ", gdb_stdout
);
1684 print_address (pc
, gdb_stdout
);
1685 fputs_unfiltered (":\t ", gdb_stdout
);
1686 pc
+= (*tm_print_insn
) (pc
, &di
);
1687 fputs_unfiltered ("\n", gdb_stdout
);
1691 gdb_flush (gdb_stdout
);
1697 tk_command (cmd
, from_tty
)
1703 struct cleanup
*old_chain
;
1705 /* Catch case of no argument, since this will make the tcl interpreter dump core. */
1707 error_no_arg ("tcl command to interpret");
1709 retval
= Tcl_Eval (interp
, cmd
);
1711 result
= strdup (interp
->result
);
1713 old_chain
= make_cleanup (free
, result
);
1715 if (retval
!= TCL_OK
)
1718 printf_unfiltered ("%s\n", result
);
1720 do_cleanups (old_chain
);
1724 cleanup_init (ignored
)
1728 Tcl_DeleteInterp (interp
);
1732 /* Come here during long calculations to check for GUI events. Usually invoked
1733 via the QUIT macro. */
1736 gdbtk_interactive ()
1738 /* Tk_DoOneEvent (TK_DONT_WAIT|TK_IDLE_EVENTS); */
1741 /* Come here when there is activity on the X file descriptor. */
1747 static int in_x_event
= 0;
1748 static Tcl_Obj
*varname
= NULL
;
1749 if (in_x_event
|| in_fputs
)
1754 /* Process pending events */
1755 while (Tcl_DoOneEvent (TCL_DONT_WAIT
|TCL_ALL_EVENTS
) != 0)
1758 if (load_in_progress
)
1761 if (varname
== NULL
)
1763 Tcl_Obj
*varnamestrobj
= Tcl_NewStringObj("download_cancel_ok",-1);
1764 varname
= Tcl_ObjGetVar2(interp
,varnamestrobj
,NULL
,TCL_GLOBAL_ONLY
);
1766 if ((Tcl_GetIntFromObj(interp
,varname
,&val
) == TCL_OK
) && val
)
1780 /* For Cygwin32, we use a timer to periodically check for Windows
1781 messages. FIXME: It would be better to not poll, but to instead
1782 rewrite the target_wait routines to serve as input sources.
1783 Unfortunately, that will be a lot of work. */
1784 static sigset_t nullsigmask
;
1785 static struct sigaction act1
, act2
;
1786 static struct itimerval it_on
, it_off
;
1789 gdbtk_start_timer ()
1791 static int first
= 1;
1792 /*TclDebug ("Starting timer....");*/
1795 /* first time called, set up all the structs */
1797 sigemptyset (&nullsigmask
);
1799 act1
.sa_handler
= x_event
;
1800 act1
.sa_mask
= nullsigmask
;
1803 act2
.sa_handler
= SIG_IGN
;
1804 act2
.sa_mask
= nullsigmask
;
1807 it_on
.it_interval
.tv_sec
= 0;
1808 it_on
.it_interval
.tv_usec
= 250000; /* .25 sec */
1809 it_on
.it_value
.tv_sec
= 0;
1810 it_on
.it_value
.tv_usec
= 250000;
1812 it_off
.it_interval
.tv_sec
= 0;
1813 it_off
.it_interval
.tv_usec
= 0;
1814 it_off
.it_value
.tv_sec
= 0;
1815 it_off
.it_value
.tv_usec
= 0;
1818 if (!gdbtk_timer_going
)
1820 sigaction (SIGALRM
, &act1
, NULL
);
1821 setitimer (ITIMER_REAL
, &it_on
, NULL
);
1822 gdbtk_timer_going
= 1;
1829 if (gdbtk_timer_going
)
1831 gdbtk_timer_going
= 0;
1832 /*TclDebug ("Stopping timer.");*/
1833 setitimer (ITIMER_REAL
, &it_off
, NULL
);
1834 sigaction (SIGALRM
, &act2
, NULL
);
1838 /* This hook function is called whenever we want to wait for the
1842 gdbtk_wait (pid
, ourstatus
)
1844 struct target_waitstatus
*ourstatus
;
1846 gdbtk_start_timer ();
1847 pid
= target_wait (pid
, ourstatus
);
1848 gdbtk_stop_timer ();
1852 /* This is called from execute_command, and provides a wrapper around
1853 various command routines in a place where both protocol messages and
1854 user input both flow through. Mostly this is used for indicating whether
1855 the target process is running or not.
1859 gdbtk_call_command (cmdblk
, arg
, from_tty
)
1860 struct cmd_list_element
*cmdblk
;
1865 if (cmdblk
->class == class_run
|| cmdblk
->class == class_trace
)
1869 Tcl_Eval (interp
, "gdbtk_tcl_busy");
1870 (*cmdblk
->function
.cfunc
)(arg
, from_tty
);
1873 Tcl_Eval (interp
, "gdbtk_tcl_idle");
1876 (*cmdblk
->function
.cfunc
)(arg
, from_tty
);
1879 /* This function is called instead of gdb's internal command loop. This is the
1880 last chance to do anything before entering the main Tk event loop. */
1885 extern GDB_FILE
*instream
;
1887 /* We no longer want to use stdin as the command input stream */
1890 if (Tcl_Eval (interp
, "gdbtk_tcl_preloop") != TCL_OK
)
1894 /* Force errorInfo to be set up propertly. */
1895 Tcl_AddErrorInfo (interp
, "");
1897 msg
= Tcl_GetVar (interp
, "errorInfo", TCL_GLOBAL_ONLY
);
1899 MessageBox (NULL
, msg
, NULL
, MB_OK
| MB_ICONERROR
| MB_TASKMODAL
);
1901 fputs_unfiltered (msg
, gdb_stderr
);
1912 /* gdbtk_init installs this function as a final cleanup. */
1915 gdbtk_cleanup (dummy
)
1919 struct ide_event_handle
*h
= (struct ide_event_handle
*) dummy
;
1921 ide_interface_deregister_all (h
);
1926 /* Initialize gdbtk. */
1929 gdbtk_init ( argv0
)
1932 struct cleanup
*old_chain
;
1933 char *lib
, *gdbtk_lib
, *gdbtk_lib_tmp
, *gdbtk_file
;
1936 struct sigaction action
;
1937 static sigset_t nullsigmask
= {0};
1940 /* start-sanitize-ide */
1941 struct ide_event_handle
*h
;
1944 /* end-sanitize-ide */
1947 /* If there is no DISPLAY environment variable, Tk_Init below will fail,
1948 causing gdb to abort. If instead we simply return here, gdb will
1949 gracefully degrade to using the command line interface. */
1952 if (getenv ("DISPLAY") == NULL
)
1956 old_chain
= make_cleanup (cleanup_init
, 0);
1958 /* First init tcl and tk. */
1959 Tcl_FindExecutable (argv0
);
1960 interp
= Tcl_CreateInterp ();
1962 #ifdef TCL_MEM_DEBUG
1963 Tcl_InitMemory (interp
);
1967 error ("Tcl_CreateInterp failed");
1969 if (Tcl_Init(interp
) != TCL_OK
)
1970 error ("Tcl_Init failed: %s", interp
->result
);
1973 /* For the IDE we register the cleanup later, after we've
1974 initialized events. */
1975 make_final_cleanup (gdbtk_cleanup
, NULL
);
1978 /* Initialize the Paths variable. */
1979 if (ide_initialize_paths (interp
, "gdbtcl") != TCL_OK
)
1980 error ("ide_initialize_paths failed: %s", interp
->result
);
1983 /* start-sanitize-ide */
1984 /* Find the directory where we expect to find idemanager. We ignore
1985 errors since it doesn't really matter if this fails. */
1986 libexecdir
= Tcl_GetVar2 (interp
, "Paths", "libexecdir", TCL_GLOBAL_ONLY
);
1990 h
= ide_event_init_from_environment (&errmsg
, libexecdir
);
1991 make_final_cleanup (gdbtk_cleanup
, h
);
1994 Tcl_AppendResult (interp
, "can't initialize event system: ", errmsg
,
1996 fprintf(stderr
, "WARNING: ide_event_init_client failed: %s\n", interp
->result
);
1998 Tcl_SetVar (interp
, "GDBTK_IDE", "0", 0);
2002 if (ide_create_tclevent_command (interp
, h
) != TCL_OK
)
2003 error ("ide_create_tclevent_command failed: %s", interp
->result
);
2005 if (ide_create_edit_command (interp
, h
) != TCL_OK
)
2006 error ("ide_create_edit_command failed: %s", interp
->result
);
2008 if (ide_create_property_command (interp
, h
) != TCL_OK
)
2009 error ("ide_create_property_command failed: %s", interp
->result
);
2011 if (ide_create_build_command (interp
, h
) != TCL_OK
)
2012 error ("ide_create_build_command failed: %s", interp
->result
);
2014 if (ide_create_window_register_command (interp
, h
, "gdb-restore")
2016 error ("ide_create_window_register_command failed: %s",
2019 if (ide_create_window_command (interp
, h
) != TCL_OK
)
2020 error ("ide_create_window_command failed: %s", interp
->result
);
2022 if (ide_create_exit_command (interp
, h
) != TCL_OK
)
2023 error ("ide_create_exit_command failed: %s", interp
->result
);
2025 if (ide_create_help_command (interp
) != TCL_OK
)
2026 error ("ide_create_help_command failed: %s", interp
->result
);
2029 if (ide_initialize (interp, "gdb") != TCL_OK)
2030 error ("ide_initialize failed: %s", interp->result);
2033 Tcl_SetVar (interp
, "GDBTK_IDE", "1", 0);
2035 /* end-sanitize-ide */
2037 Tcl_SetVar (interp
, "GDBTK_IDE", "0", 0);
2040 /* We don't want to open the X connection until we've done all the
2041 IDE initialization. Otherwise, goofy looking unfinished windows
2042 pop up when ILU drops into the TCL event loop. */
2044 if (Tk_Init(interp
) != TCL_OK
)
2045 error ("Tk_Init failed: %s", interp
->result
);
2047 if (Itcl_Init(interp
) == TCL_ERROR
)
2048 error ("Itcl_Init failed: %s", interp
->result
);
2050 if (Tix_Init(interp
) != TCL_OK
)
2051 error ("Tix_Init failed: %s", interp
->result
);
2054 if (ide_create_messagebox_command (interp
) != TCL_OK
)
2055 error ("messagebox command initialization failed");
2056 /* On Windows, create a sizebox widget command */
2057 if (ide_create_sizebox_command (interp
) != TCL_OK
)
2058 error ("sizebox creation failed");
2059 if (ide_create_winprint_command (interp
) != TCL_OK
)
2060 error ("windows print code initialization failed");
2061 /* start-sanitize-ide */
2062 /* An interface to ShellExecute. */
2063 if (ide_create_shell_execute_command (interp
) != TCL_OK
)
2064 error ("shell execute command initialization failed");
2065 /* end-sanitize-ide */
2066 if (ide_create_win_grab_command (interp
) != TCL_OK
)
2067 error ("grab support command initialization failed");
2068 /* Path conversion functions. */
2069 if (ide_create_cygwin_path_command (interp
) != TCL_OK
)
2070 error ("cygwin path command initialization failed");
2073 Tcl_CreateCommand (interp
, "gdb_cmd", call_wrapper
, gdb_cmd
, NULL
);
2074 Tcl_CreateCommand (interp
, "gdb_immediate", call_wrapper
,
2075 gdb_immediate_command
, NULL
);
2076 Tcl_CreateCommand (interp
, "gdb_loc", call_wrapper
, gdb_loc
, NULL
);
2077 Tcl_CreateCommand (interp
, "gdb_path_conv", call_wrapper
, gdb_path_conv
, NULL
);
2078 Tcl_CreateObjCommand (interp
, "gdb_listfiles", gdb_listfiles
, NULL
, NULL
);
2079 Tcl_CreateCommand (interp
, "gdb_listfuncs", call_wrapper
, gdb_listfuncs
,
2081 Tcl_CreateCommand (interp
, "gdb_get_mem", call_wrapper
, gdb_get_mem
,
2083 Tcl_CreateCommand (interp
, "gdb_stop", call_wrapper
, gdb_stop
, NULL
);
2084 Tcl_CreateCommand (interp
, "gdb_regnames", call_wrapper
, gdb_regnames
, NULL
);
2085 Tcl_CreateCommand (interp
, "gdb_fetch_registers", call_wrapper
,
2086 gdb_fetch_registers
, NULL
);
2087 Tcl_CreateCommand (interp
, "gdb_changed_register_list", call_wrapper
,
2088 gdb_changed_register_list
, NULL
);
2089 Tcl_CreateCommand (interp
, "gdb_disassemble", call_wrapper
,
2090 gdb_disassemble
, NULL
);
2091 Tcl_CreateCommand (interp
, "gdb_eval", call_wrapper
, gdb_eval
, NULL
);
2092 Tcl_CreateCommand (interp
, "gdb_get_breakpoint_list", call_wrapper
,
2093 gdb_get_breakpoint_list
, NULL
);
2094 Tcl_CreateCommand (interp
, "gdb_get_breakpoint_info", call_wrapper
,
2095 gdb_get_breakpoint_info
, NULL
);
2096 Tcl_CreateCommand (interp
, "gdb_clear_file", call_wrapper
,
2097 gdb_clear_file
, NULL
);
2098 Tcl_CreateCommand (interp
, "gdb_confirm_quit", call_wrapper
,
2099 gdb_confirm_quit
, NULL
);
2100 Tcl_CreateCommand (interp
, "gdb_force_quit", call_wrapper
,
2101 gdb_force_quit
, NULL
);
2102 Tcl_CreateCommand (interp
, "gdb_target_has_execution",
2103 gdb_target_has_execution_command
,
2105 Tcl_CreateCommand (interp
, "gdb_is_tracing",
2108 Tcl_CreateObjCommand (interp
, "gdb_load_info", gdb_load_info
, NULL
, NULL
);
2109 Tcl_CreateObjCommand (interp
, "gdb_get_locals", gdb_get_vars_command
,
2110 (ClientData
) 0, NULL
);
2111 Tcl_CreateObjCommand (interp
, "gdb_get_args", gdb_get_vars_command
,
2112 (ClientData
) 1, NULL
);
2113 Tcl_CreateObjCommand (interp
, "gdb_get_function", gdb_get_function_command
,
2115 Tcl_CreateObjCommand (interp
, "gdb_get_line", gdb_get_line_command
,
2117 Tcl_CreateObjCommand (interp
, "gdb_get_file", gdb_get_file_command
,
2119 Tcl_CreateObjCommand (interp
, "gdb_tracepoint_exists",
2120 gdb_tracepoint_exists_command
, NULL
, NULL
);
2121 Tcl_CreateObjCommand (interp
, "gdb_get_tracepoint_info",
2122 gdb_get_tracepoint_info
, NULL
, NULL
);
2123 Tcl_CreateObjCommand (interp
, "gdb_actions",
2124 gdb_actions_command
, NULL
, NULL
);
2125 Tcl_CreateObjCommand (interp
, "gdb_prompt",
2126 gdb_prompt_command
, NULL
, NULL
);
2127 Tcl_CreateObjCommand (interp
, "gdb_find_file",
2128 gdb_find_file_command
, NULL
, NULL
);
2129 Tcl_CreateObjCommand (interp
, "gdb_get_tracepoint_list",
2130 gdb_get_tracepoint_list
, NULL
, NULL
);
2131 Tcl_CreateCommand (interp
, "gdb_pc_reg", get_pc_register
, NULL
, NULL
);
2132 Tcl_CreateObjCommand (interp
, "gdb_loadfile", gdb_loadfile
, NULL
, NULL
);
2133 Tcl_CreateObjCommand (interp
, "gdb_set_bp", gdb_set_bp
, NULL
, NULL
);
2135 command_loop_hook
= tk_command_loop
;
2136 print_frame_info_listing_hook
= gdbtk_print_frame_info
;
2137 query_hook
= gdbtk_query
;
2138 flush_hook
= gdbtk_flush
;
2139 create_breakpoint_hook
= gdbtk_create_breakpoint
;
2140 delete_breakpoint_hook
= gdbtk_delete_breakpoint
;
2141 modify_breakpoint_hook
= gdbtk_modify_breakpoint
;
2142 interactive_hook
= gdbtk_interactive
;
2143 target_wait_hook
= gdbtk_wait
;
2144 call_command_hook
= gdbtk_call_command
;
2145 readline_begin_hook
= gdbtk_readline_begin
;
2146 readline_hook
= gdbtk_readline
;
2147 readline_end_hook
= gdbtk_readline_end
;
2148 ui_load_progress_hook
= gdbtk_load_hash
;
2149 pre_add_symbol_hook
= gdbtk_pre_add_symbol
;
2150 post_add_symbol_hook
= gdbtk_post_add_symbol
;
2151 create_tracepoint_hook
= gdbtk_create_tracepoint
;
2152 delete_tracepoint_hook
= gdbtk_delete_tracepoint
;
2153 modify_tracepoint_hook
= gdbtk_modify_tracepoint
;
2154 pc_changed_hook
= pc_changed
;
2156 add_com ("tk", class_obscure
, tk_command
,
2157 "Send a command directly into tk.");
2159 Tcl_LinkVar (interp
, "disassemble-from-exec", (char *)&disassemble_from_exec
,
2162 /* find the gdb tcl library and source main.tcl */
2164 gdbtk_lib
= getenv ("GDBTK_LIBRARY");
2166 if (access ("gdbtcl/main.tcl", R_OK
) == 0)
2167 gdbtk_lib
= "gdbtcl";
2169 gdbtk_lib
= GDBTK_LIBRARY
;
2171 gdbtk_lib_tmp
= xstrdup (gdbtk_lib
);
2174 /* see if GDBTK_LIBRARY is a path list */
2175 lib
= strtok (gdbtk_lib_tmp
, GDBTK_PATH_SEP
);
2178 if (Tcl_VarEval (interp
, "lappend auto_path ", lib
, NULL
) != TCL_OK
)
2180 fputs_unfiltered (Tcl_GetVar (interp
, "errorInfo", 0), gdb_stderr
);
2185 gdbtk_file
= concat (lib
, "/main.tcl", (char *) NULL
);
2186 if (access (gdbtk_file
, R_OK
) == 0)
2189 Tcl_SetVar (interp
, "GDBTK_LIBRARY", lib
, 0);
2193 while ((lib
= strtok (NULL
, ":")) != NULL
);
2195 free (gdbtk_lib_tmp
);
2199 /* Try finding it with the auto path. */
2201 static const char script
[] ="\
2202 proc gdbtk_find_main {} {\n\
2203 global auto_path GDBTK_LIBRARY\n\
2204 foreach dir $auto_path {\n\
2205 set f [file join $dir main.tcl]\n\
2206 if {[file exists $f]} then {\n\
2207 set GDBTK_LIBRARY $dir\n\
2215 if (Tcl_GlobalEval (interp
, (char *) script
) != TCL_OK
)
2217 fputs_unfiltered (Tcl_GetVar (interp
, "errorInfo", 0), gdb_stderr
);
2221 if (interp
->result
[0] != '\0')
2223 gdbtk_file
= xstrdup (interp
->result
);
2230 fputs_unfiltered_hook
= NULL
; /* Force errors to stdout/stderr */
2231 if (getenv("GDBTK_LIBRARY"))
2233 fprintf_unfiltered (stderr
, "Unable to find main.tcl in %s\n",getenv("GDBTK_LIBRARY"));
2234 fprintf_unfiltered (stderr
,
2235 "Please set GDBTK_LIBRARY to a path that includes the GDB tcl files.\n");
2239 fprintf_unfiltered (stderr
, "Unable to find main.tcl in %s\n", GDBTK_LIBRARY
);
2240 fprintf_unfiltered (stderr
, "You might want to set GDBTK_LIBRARY\n");
2245 /* Defer setup of fputs_unfiltered_hook to near the end so that error messages
2246 prior to this point go to stdout/stderr. */
2248 fputs_unfiltered_hook
= gdbtk_fputs
;
2250 if (Tcl_EvalFile (interp
, gdbtk_file
) != TCL_OK
)
2254 /* Force errorInfo to be set up propertly. */
2255 Tcl_AddErrorInfo (interp
, "");
2257 msg
= Tcl_GetVar (interp
, "errorInfo", TCL_GLOBAL_ONLY
);
2259 fputs_unfiltered_hook
= NULL
; /* Force errors to stdout/stderr */
2262 MessageBox (NULL
, msg
, NULL
, MB_OK
| MB_ICONERROR
| MB_TASKMODAL
);
2264 fputs_unfiltered (msg
, gdb_stderr
);
2271 /* start-sanitize-ide */
2272 /* Don't do this until we have initialized. Otherwise, we may get a
2273 run command before we are ready for one. */
2274 if (ide_run_server_init (interp
, h
) != TCL_OK
)
2275 error ("ide_run_server_init failed: %s", interp
->result
);
2276 /* end-sanitize-ide */
2281 discard_cleanups (old_chain
);
2285 gdb_target_has_execution_command (clientData
, interp
, argc
, argv
)
2286 ClientData clientData
;
2293 if (target_has_execution
&& inferior_pid
!= 0)
2296 Tcl_SetIntObj (Tcl_GetObjResult (interp
), result
);
2301 gdb_trace_status (clientData
, interp
, argc
, argv
)
2302 ClientData clientData
;
2309 if (trace_running_p
)
2312 Tcl_SetIntObj (Tcl_GetObjResult (interp
), result
);
2316 /* gdb_load_info - returns information about the file about to be downloaded */
2319 gdb_load_info (clientData
, interp
, objc
, objv
)
2320 ClientData clientData
;
2323 Tcl_Obj
*CONST objv
[];
2326 struct cleanup
*old_cleanups
;
2332 char *filename
= Tcl_GetStringFromObj (objv
[1], NULL
);
2334 loadfile_bfd
= bfd_openr (filename
, gnutarget
);
2335 if (loadfile_bfd
== NULL
)
2337 Tcl_SetObjResult (interp
, Tcl_NewStringObj ("Open failed", -1));
2340 old_cleanups
= make_cleanup (bfd_close
, loadfile_bfd
);
2342 if (!bfd_check_format (loadfile_bfd
, bfd_object
))
2344 Tcl_SetObjResult (interp
, Tcl_NewStringObj ("Bad Object File", -1));
2348 for (s
= loadfile_bfd
->sections
; s
; s
= s
->next
)
2350 if (s
->flags
& SEC_LOAD
)
2352 bfd_size_type size
= bfd_get_section_size_before_reloc (s
);
2355 ob
[0] = Tcl_NewStringObj((char *)bfd_get_section_name(loadfile_bfd
, s
), -1);
2356 ob
[1] = Tcl_NewLongObj ((long)size
);
2357 res
[i
++] = Tcl_NewListObj (2, ob
);
2362 Tcl_SetObjResult (interp
, Tcl_NewListObj (i
, res
));
2363 do_cleanups (old_cleanups
);
2369 gdbtk_load_hash (section
, num
)
2374 sprintf (buf
, "download_hash %s %ld", section
, num
);
2375 Tcl_Eval (interp
, buf
);
2376 return atoi (interp
->result
);
2379 /* gdb_get_vars_command -
2381 * Implements the "gdb_get_locals" and "gdb_get_args" tcl commands. This
2382 * function sets the Tcl interpreter's result to a list of variable names
2383 * depending on clientData. If clientData is one, the result is a list of
2384 * arguments; zero returns a list of locals -- all relative to the block
2385 * specified as an argument to the command. Valid commands include
2386 * anything decode_line_1 can handle (like "main.c:2", "*0x02020202",
2390 gdb_get_vars_command (clientData
, interp
, objc
, objv
)
2391 ClientData clientData
;
2394 Tcl_Obj
*CONST objv
[];
2397 struct symtabs_and_lines sals
;
2399 struct block
*block
;
2400 char **canonical
, *args
;
2401 int i
, nsyms
, arguments
;
2405 Tcl_AppendResult (interp
,
2406 "wrong # of args: should be \"",
2407 Tcl_GetStringFromObj (objv
[0], NULL
),
2408 " function:line|function|line|*addr\"");
2412 arguments
= (int) clientData
;
2413 args
= Tcl_GetStringFromObj (objv
[1], NULL
);
2414 sals
= decode_line_1 (&args
, 1, NULL
, 0, &canonical
);
2415 if (sals
.nelts
== 0)
2417 Tcl_AppendResult (interp
,
2418 "error decoding line", NULL
);
2422 /* Initialize a list that will hold the results */
2423 result
= Tcl_NewListObj (0, NULL
);
2425 /* Resolve all line numbers to PC's */
2426 for (i
= 0; i
< sals
.nelts
; i
++)
2427 resolve_sal_pc (&sals
.sals
[i
]);
2429 block
= block_for_pc (sals
.sals
[0].pc
);
2432 nsyms
= BLOCK_NSYMS (block
);
2433 for (i
= 0; i
< nsyms
; i
++)
2435 sym
= BLOCK_SYM (block
, i
);
2436 switch (SYMBOL_CLASS (sym
)) {
2438 case LOC_UNDEF
: /* catches errors */
2439 case LOC_CONST
: /* constant */
2440 case LOC_STATIC
: /* static */
2441 case LOC_REGISTER
: /* register */
2442 case LOC_TYPEDEF
: /* local typedef */
2443 case LOC_LABEL
: /* local label */
2444 case LOC_BLOCK
: /* local function */
2445 case LOC_CONST_BYTES
: /* loc. byte seq. */
2446 case LOC_UNRESOLVED
: /* unresolved static */
2447 case LOC_OPTIMIZED_OUT
: /* optimized out */
2449 case LOC_ARG
: /* argument */
2450 case LOC_REF_ARG
: /* reference arg */
2451 case LOC_REGPARM
: /* register arg */
2452 case LOC_REGPARM_ADDR
: /* indirect register arg */
2453 case LOC_LOCAL_ARG
: /* stack arg */
2454 case LOC_BASEREG_ARG
: /* basereg arg */
2456 Tcl_ListObjAppendElement (interp
, result
,
2457 Tcl_NewStringObj (SYMBOL_NAME (sym
), -1));
2459 case LOC_LOCAL
: /* stack local */
2460 case LOC_BASEREG
: /* basereg local */
2462 Tcl_ListObjAppendElement (interp
, result
,
2463 Tcl_NewStringObj (SYMBOL_NAME (sym
), -1));
2467 if (BLOCK_FUNCTION (block
))
2470 block
= BLOCK_SUPERBLOCK (block
);
2473 Tcl_SetObjResult (interp
, result
);
2478 gdb_get_line_command (clientData
, interp
, objc
, objv
)
2479 ClientData clientData
;
2482 Tcl_Obj
*CONST objv
[];
2485 struct symtabs_and_lines sals
;
2486 char *args
, **canonical
;
2490 Tcl_AppendResult (interp
, "wrong # of args: should be \"",
2491 Tcl_GetStringFromObj (objv
[0], NULL
),
2496 args
= Tcl_GetStringFromObj (objv
[1], NULL
);
2497 sals
= decode_line_1 (&args
, 1, NULL
, 0, &canonical
);
2498 if (sals
.nelts
== 1)
2500 Tcl_SetObjResult (interp
, Tcl_NewIntObj (sals
.sals
[0].line
));
2504 Tcl_SetResult (interp
, "N/A", TCL_STATIC
);
2509 gdb_get_file_command (clientData
, interp
, objc
, objv
)
2510 ClientData clientData
;
2513 Tcl_Obj
*CONST objv
[];
2516 struct symtabs_and_lines sals
;
2517 char *args
, **canonical
;
2521 Tcl_AppendResult (interp
, "wrong # of args: should be \"",
2522 Tcl_GetStringFromObj (objv
[0], NULL
),
2527 args
= Tcl_GetStringFromObj (objv
[1], NULL
);
2528 sals
= decode_line_1 (&args
, 1, NULL
, 0, &canonical
);
2529 if (sals
.nelts
== 1)
2531 Tcl_SetResult (interp
, sals
.sals
[0].symtab
->filename
, TCL_VOLATILE
);
2535 Tcl_SetResult (interp
, "N/A", TCL_STATIC
);
2540 gdb_get_function_command (clientData
, interp
, objc
, objv
)
2541 ClientData clientData
;
2544 Tcl_Obj
*CONST objv
[];
2548 struct symtabs_and_lines sals
;
2549 char *args
, **canonical
;
2553 Tcl_AppendResult (interp
, "wrong # of args: should be \"",
2554 Tcl_GetStringFromObj (objv
[0], NULL
),
2559 args
= Tcl_GetStringFromObj (objv
[1], NULL
);
2560 sals
= decode_line_1 (&args
, 1, NULL
, 0, &canonical
);
2561 if (sals
.nelts
== 1)
2563 resolve_sal_pc (&sals
.sals
[0]);
2564 find_pc_partial_function (sals
.sals
[0].pc
, &function
, NULL
, NULL
);
2565 if (function
!= NULL
)
2567 Tcl_SetResult (interp
, function
, TCL_VOLATILE
);
2572 Tcl_SetResult (interp
, "N/A", TCL_STATIC
);
2577 gdb_get_tracepoint_info (clientData
, interp
, objc
, objv
)
2578 ClientData clientData
;
2581 Tcl_Obj
*CONST objv
[];
2583 struct symtab_and_line sal
;
2585 struct tracepoint
*tp
;
2586 struct action_line
*al
;
2587 Tcl_Obj
*list
, *action_list
;
2588 char *filename
, *funcname
;
2592 error ("wrong # args");
2594 Tcl_GetIntFromObj (NULL
, objv
[1], &tpnum
);
2596 ALL_TRACEPOINTS (tp
)
2597 if (tp
->number
== tpnum
)
2601 error ("Tracepoint #%d does not exist", tpnum
);
2603 list
= Tcl_NewListObj (0, NULL
);
2604 sal
= find_pc_line (tp
->address
, 0);
2605 filename
= symtab_to_filename (sal
.symtab
);
2606 if (filename
== NULL
)
2608 Tcl_ListObjAppendElement (interp
, list
,
2609 Tcl_NewStringObj (filename
, -1));
2610 find_pc_partial_function (tp
->address
, &funcname
, NULL
, NULL
);
2611 Tcl_ListObjAppendElement (interp
, list
, Tcl_NewStringObj (funcname
, -1));
2612 Tcl_ListObjAppendElement (interp
, list
, Tcl_NewIntObj (sal
.line
));
2613 sprintf (tmp
, "0x%lx", tp
->address
);
2614 Tcl_ListObjAppendElement (interp
, list
, Tcl_NewStringObj (tmp
, -1));
2615 Tcl_ListObjAppendElement (interp
, list
, Tcl_NewIntObj (tp
->enabled
));
2616 Tcl_ListObjAppendElement (interp
, list
, Tcl_NewIntObj (tp
->pass_count
));
2617 Tcl_ListObjAppendElement (interp
, list
, Tcl_NewIntObj (tp
->step_count
));
2618 Tcl_ListObjAppendElement (interp
, list
, Tcl_NewIntObj (tp
->thread
));
2619 Tcl_ListObjAppendElement (interp
, list
, Tcl_NewIntObj (tp
->hit_count
));
2621 /* Append a list of actions */
2622 action_list
= Tcl_NewListObj (0, NULL
);
2623 for (al
= tp
->actions
; al
!= NULL
; al
= al
->next
)
2625 Tcl_ListObjAppendElement (interp
, action_list
,
2626 Tcl_NewStringObj (al
->action
, -1));
2628 Tcl_ListObjAppendElement (interp
, list
, action_list
);
2630 Tcl_SetObjResult (interp
, list
);
2635 /* TclDebug (const char *fmt, ...) works just like printf() but */
2636 /* sends the output to the GDB TK debug window. */
2637 /* Not for normal use; just a convenient tool for debugging */
2639 #ifdef ANSI_PROTOTYPES
2640 TclDebug (const char *fmt
, ...)
2647 char buf
[512], *v
[2], *merge
;
2649 #ifdef ANSI_PROTOTYPES
2650 va_start (args
, fmt
);
2654 fmt
= va_arg (args
, char *);
2660 vsprintf (buf
, fmt
, args
);
2663 merge
= Tcl_Merge (2, v
);
2664 Tcl_Eval (interp
, merge
);
2669 /* Find the full pathname to a file, searching the symbol tables */
2672 gdb_find_file_command (clientData
, interp
, objc
, objv
)
2673 ClientData clientData
;
2676 Tcl_Obj
*CONST objv
[];
2678 char *filename
= NULL
;
2683 Tcl_WrongNumArgs(interp
, 1, objv
, "filename");
2687 st
= full_lookup_symtab (Tcl_GetStringFromObj (objv
[1], NULL
));
2689 filename
= st
->fullname
;
2691 if (filename
== NULL
)
2692 Tcl_SetObjResult (interp
, Tcl_NewStringObj ("", 0));
2694 Tcl_SetObjResult (interp
, Tcl_NewStringObj (filename
, -1));
2700 gdbtk_create_tracepoint (tp
)
2701 struct tracepoint
*tp
;
2703 tracepoint_notify (tp
, "create");
2707 gdbtk_delete_tracepoint (tp
)
2708 struct tracepoint
*tp
;
2710 tracepoint_notify (tp
, "delete");
2714 gdbtk_modify_tracepoint (tp
)
2715 struct tracepoint
*tp
;
2717 tracepoint_notify (tp
, "modify");
2721 tracepoint_notify(tp
, action
)
2722 struct tracepoint
*tp
;
2727 struct symtab_and_line sal
;
2730 /* We ensure that ACTION contains no special Tcl characters, so we
2732 sal
= find_pc_line (tp
->address
, 0);
2734 filename
= symtab_to_filename (sal
.symtab
);
2735 if (filename
== NULL
)
2737 sprintf (buf
, "gdbtk_tcl_tracepoint %s %d 0x%lx %d {%s}", action
, tp
->number
,
2738 (long)tp
->address
, sal
.line
, filename
, tp
->pass_count
);
2740 v
= Tcl_Eval (interp
, buf
);
2744 gdbtk_fputs (interp
->result
, gdb_stdout
);
2745 gdbtk_fputs ("\n", gdb_stdout
);
2749 /* returns -1 if not found, tracepoint # if found */
2751 tracepoint_exists (char * args
)
2753 struct tracepoint
*tp
;
2755 struct symtabs_and_lines sals
;
2759 sals
= decode_line_1 (&args
, 1, NULL
, 0, &canonical
);
2760 if (sals
.nelts
== 1)
2762 resolve_sal_pc (&sals
.sals
[0]);
2763 file
= xmalloc (strlen (sals
.sals
[0].symtab
->dirname
)
2764 + strlen (sals
.sals
[0].symtab
->filename
) + 1);
2767 strcpy (file
, sals
.sals
[0].symtab
->dirname
);
2768 strcat (file
, sals
.sals
[0].symtab
->filename
);
2770 ALL_TRACEPOINTS (tp
)
2772 if (tp
->address
== sals
.sals
[0].pc
)
2773 result
= tp
->number
;
2775 /* Why is this here? This messes up assembly traces */
2776 else if (tp
->source_file
!= NULL
2777 && strcmp (tp
->source_file
, file
) == 0
2778 && sals
.sals
[0].line
== tp
->line_number
)
2779 result
= tp
->number
;
2790 gdb_actions_command (clientData
, interp
, objc
, objv
)
2791 ClientData clientData
;
2794 Tcl_Obj
*CONST objv
[];
2796 struct tracepoint
*tp
;
2798 int nactions
, i
, len
;
2799 char *number
, *args
, *action
;
2801 struct action_line
*next
= NULL
, *temp
;
2805 Tcl_AppendResult (interp
, "wrong # args: should be: \"",
2806 Tcl_GetStringFromObj (objv
[0], NULL
),
2807 " number actions\"");
2811 args
= number
= Tcl_GetStringFromObj (objv
[1], NULL
);
2812 tp
= get_tracepoint_by_number (&args
);
2815 Tcl_AppendResult (interp
, "Tracepoint \"", number
, "\" does not exist");
2819 /* Free any existing actions */
2820 if (tp
->actions
!= NULL
)
2825 Tcl_ListObjGetElements (interp
, objv
[2], &nactions
, &actions
);
2826 for (i
= 0; i
< nactions
; i
++)
2828 temp
= xmalloc (sizeof (struct action_line
));
2830 action
= Tcl_GetStringFromObj (actions
[i
], &len
);
2831 temp
->action
= savestring (action
, len
);
2832 if (sscanf (temp
->action
, "while-stepping %d", &step_count
) !=0)
2833 tp
->step_count
= step_count
;
2850 gdb_tracepoint_exists_command (clientData
, interp
, objc
, objv
)
2851 ClientData clientData
;
2854 Tcl_Obj
*CONST objv
[];
2860 Tcl_AppendResult (interp
, "wrong # of args: should be \"",
2861 Tcl_GetStringFromObj (objv
[0], NULL
),
2862 " function:line|function|line|*addr\"");
2866 args
= Tcl_GetStringFromObj (objv
[1], NULL
);
2868 Tcl_SetObjResult (interp
, Tcl_NewIntObj (tracepoint_exists (args
)));
2872 /* Return the prompt to the interpreter */
2874 gdb_prompt_command (clientData
, interp
, objc
, objv
)
2875 ClientData clientData
;
2878 Tcl_Obj
*CONST objv
[];
2880 Tcl_SetResult (interp
, get_prompt (), TCL_VOLATILE
);
2884 /* return a list of all tracepoint numbers in interpreter */
2886 gdb_get_tracepoint_list (clientData
, interp
, objc
, objv
)
2887 ClientData clientData
;
2890 Tcl_Obj
*CONST objv
[];
2893 struct tracepoint
*tp
;
2895 list
= Tcl_NewListObj (0, NULL
);
2897 ALL_TRACEPOINTS (tp
)
2898 Tcl_ListObjAppendElement (interp
, list
, Tcl_NewIntObj (tp
->number
));
2900 Tcl_SetObjResult (interp
, list
);
2905 /* This hook is called whenever we are ready to load a symbol file so that
2906 the UI can notify the user... */
2908 gdbtk_pre_add_symbol (name
)
2913 v
[0] = "gdbtk_tcl_pre_add_symbol";
2915 merge
= Tcl_Merge (2, v
);
2916 Tcl_Eval (interp
, merge
);
2920 /* This hook is called whenever we finish loading a symbol file. */
2922 gdbtk_post_add_symbol ()
2924 Tcl_Eval (interp
, "gdbtk_tcl_post_add_symbol");
2930 gdbtk_print_frame_info (s
, line
, stopline
, noerror
)
2936 current_source_symtab
= s
;
2937 current_source_line
= line
;
2941 /* The lookup_symtab() in symtab.c doesn't work correctly */
2942 /* It will not work will full pathnames and if multiple */
2943 /* source files have the same basename, it will return */
2944 /* the first one instead of the correct one. This version */
2945 /* also always makes sure symtab->fullname is set. */
2947 static struct symtab
*
2948 full_lookup_symtab(file
)
2952 struct objfile
*objfile
;
2953 char *bfile
, *fullname
;
2954 struct partial_symtab
*pt
;
2959 /* first try a direct lookup */
2960 st
= lookup_symtab (file
);
2964 symtab_to_filename(st
);
2968 /* if the direct approach failed, try */
2969 /* looking up the basename and checking */
2970 /* all matches with the fullname */
2971 bfile
= basename (file
);
2972 ALL_SYMTABS (objfile
, st
)
2974 if (!strcmp (bfile
, basename(st
->filename
)))
2977 fullname
= symtab_to_filename (st
);
2979 fullname
= st
->fullname
;
2981 if (!strcmp (file
, fullname
))
2986 /* still no luck? look at psymtabs */
2987 ALL_PSYMTABS (objfile
, pt
)
2989 if (!strcmp (bfile
, basename(pt
->filename
)))
2991 st
= PSYMTAB_TO_SYMTAB (pt
);
2994 fullname
= symtab_to_filename (st
);
2995 if (!strcmp (file
, fullname
))
3004 /* gdb_loadfile loads a c source file into a text widget. */
3006 /* LTABLE_SIZE is the number of bytes to allocate for the */
3007 /* line table. Its size limits the maximum number of lines */
3008 /* in a file to 8 * LTABLE_SIZE. This memory is freed after */
3009 /* the file is loaded, so it is OK to make this very large. */
3010 /* Additional memory will be allocated if needed. */
3011 #define LTABLE_SIZE 20000
3014 gdb_loadfile (clientData
, interp
, objc
, objv
)
3015 ClientData clientData
;
3018 Tcl_Obj
*CONST objv
[];
3020 char *file
, *widget
, *line
, *buf
, msg
[128];
3021 int linenumbers
, ln
, anum
, lnum
, ltable_size
;
3022 Tcl_Obj
*a
[2], *b
[2], *cmd
;
3025 struct symtab
*symtab
;
3026 struct linetable_entry
*le
;
3030 Tcl_WrongNumArgs(interp
, 1, objv
, "widget filename linenumbers");
3034 widget
= Tcl_GetStringFromObj (objv
[1], NULL
);
3035 file
= Tcl_GetStringFromObj (objv
[2], NULL
);
3036 Tcl_GetBooleanFromObj (interp
, objv
[3], &linenumbers
);
3038 if ((fp
= fopen ( file
, "r" )) == NULL
)
3041 symtab
= full_lookup_symtab (file
);
3044 sprintf(msg
, "File not found");
3045 Tcl_SetStringObj ( Tcl_GetObjResult (interp
), msg
, -1);
3050 /* Source linenumbers don't appear to be in order, and a sort is */
3051 /* too slow so the fastest solution is just to allocate a huge */
3052 /* array and set the array entry for each linenumber */
3054 ltable_size
= LTABLE_SIZE
;
3055 ltable
= (char *)malloc (LTABLE_SIZE
);
3058 sprintf(msg
, "Out of memory.");
3059 Tcl_SetStringObj ( Tcl_GetObjResult (interp
), msg
, -1);
3064 memset (ltable
, 0, LTABLE_SIZE
);
3066 if (symtab
->linetable
&& symtab
->linetable
->nitems
)
3068 le
= symtab
->linetable
->item
;
3069 for (ln
= symtab
->linetable
->nitems
;ln
> 0; ln
--, le
++)
3071 lnum
= le
->line
>> 3;
3072 if (lnum
>= ltable_size
)
3075 new_ltable
= (char *)realloc (ltable
, ltable_size
*2);
3076 memset (new_ltable
+ ltable_size
, 0, ltable_size
);
3078 if (new_ltable
== NULL
)
3080 sprintf(msg
, "Out of memory.");
3081 Tcl_SetStringObj ( Tcl_GetObjResult (interp
), msg
, -1);
3086 ltable
= new_ltable
;
3088 ltable
[lnum
] |= 1 << (le
->line
% 8);
3092 /* create an object with enough space, then grab its */
3093 /* buffer and sprintf directly into it. */
3094 a
[0] = Tcl_NewStringObj (ltable
, 1024);
3095 a
[1] = Tcl_NewListObj(0,NULL
);
3097 b
[0] = Tcl_NewStringObj (ltable
,1024);
3098 b
[1] = Tcl_NewStringObj ("source_tag", -1);
3099 Tcl_IncrRefCount (b
[0]);
3100 Tcl_IncrRefCount (b
[1]);
3101 line
= b
[0]->bytes
+ 1;
3102 strcpy(b
[0]->bytes
,"\t");
3105 while (fgets (line
, 980, fp
))
3109 if (ltable
[ln
>> 3] & (1 << (ln
% 8)))
3111 sprintf (buf
,"%s insert end {-\t%d} break_tag", widget
, ln
);
3112 a
[0]->length
= strlen (buf
);
3116 sprintf (buf
,"%s insert end { \t%d} \"\"", widget
, ln
);
3117 a
[0]->length
= strlen (buf
);
3122 if (ltable
[ln
>> 3] & (1 << (ln
% 8)))
3124 sprintf (buf
,"%s insert end {-\t} break_tag", widget
);
3125 a
[0]->length
= strlen (buf
);
3129 sprintf (buf
,"%s insert end { \t} \"\"", widget
);
3130 a
[0]->length
= strlen (buf
);
3133 b
[0]->length
= strlen(b
[0]->bytes
);
3134 Tcl_SetListObj(a
[1],2,b
);
3135 cmd
= Tcl_ConcatObj(2,a
);
3136 Tcl_EvalObj (interp
, cmd
);
3137 Tcl_DecrRefCount (cmd
);
3140 Tcl_DecrRefCount (b
[0]);
3141 Tcl_DecrRefCount (b
[0]);
3142 Tcl_DecrRefCount (b
[1]);
3143 Tcl_DecrRefCount (b
[1]);
3149 /* at some point make these static in breakpoint.c and move GUI code there */
3150 extern struct breakpoint
*set_raw_breakpoint (struct symtab_and_line sal
);
3151 extern void set_breakpoint_count (int);
3152 extern int breakpoint_count
;
3154 /* set a breakpoint by source file and line number */
3155 /* flags are as follows: */
3156 /* least significant 2 bits are disposition, rest is */
3157 /* type (normally 0).
3160 bp_breakpoint, Normal breakpoint
3161 bp_hardware_breakpoint, Hardware assisted breakpoint
3164 Disposition of breakpoint. Ie: what to do after hitting it.
3167 del_at_next_stop, Delete at next stop, whether hit or not
3169 donttouch Leave it alone
3174 gdb_set_bp (clientData
, interp
, objc
, objv
)
3175 ClientData clientData
;
3178 Tcl_Obj
*CONST objv
[];
3181 struct symtab_and_line sal
;
3182 int line
, flags
, ret
;
3183 struct breakpoint
*b
;
3185 Tcl_Obj
*a
[5], *cmd
;
3189 Tcl_WrongNumArgs(interp
, 1, objv
, "filename line type");
3193 sal
.symtab
= full_lookup_symtab (Tcl_GetStringFromObj( objv
[1], NULL
));
3194 if (sal
.symtab
== NULL
)
3197 if (Tcl_GetIntFromObj( interp
, objv
[2], &line
) == TCL_ERROR
)
3200 if (Tcl_GetIntFromObj( interp
, objv
[3], &flags
) == TCL_ERROR
)
3204 sal
.pc
= find_line_pc (sal
.symtab
, sal
.line
);
3208 sal
.section
= find_pc_overlay (sal
.pc
);
3209 b
= set_raw_breakpoint (sal
);
3210 set_breakpoint_count (breakpoint_count
+ 1);
3211 b
->number
= breakpoint_count
;
3212 b
->type
= flags
>> 2;
3213 b
->disposition
= flags
& 3;
3215 /* FIXME: this won't work for duplicate basenames! */
3216 sprintf (buf
, "%s:%d", basename(Tcl_GetStringFromObj( objv
[1], NULL
)), line
);
3217 b
->addr_string
= strsave (buf
);
3219 /* now send notification command back to GUI */
3220 sprintf (buf
, "0x%x", sal
.pc
);
3221 a
[0] = Tcl_NewStringObj ("gdbtk_tcl_breakpoint create", -1);
3222 a
[1] = Tcl_NewIntObj (b
->number
);
3223 a
[2] = Tcl_NewStringObj (buf
, -1);
3225 a
[4] = Tcl_NewListObj (1,&objv
[1]);
3226 cmd
= Tcl_ConcatObj(5,a
);
3227 ret
= Tcl_EvalObj (interp
, cmd
);
3228 Tcl_DecrRefCount (cmd
);
3232 /* Come here during initialize_all_files () */
3235 _initialize_gdbtk ()
3239 /* Tell the rest of the world that Gdbtk is now set up. */
3241 init_ui_hook
= gdbtk_init
;