1 /* Tcl/Tk interface routines.
2 Copyright 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
4 Written by Stu Grossman <grossman@cygnus.com> of Cygnus Support.
6 This file is part of GDB.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
40 #ifdef ANSI_PROTOTYPES
50 #include <sys/ioctl.h>
51 #include "gdb_string.h"
58 #include <sys/stropts.h>
63 #define GDBTK_PATH_SEP ";"
65 #define GDBTK_PATH_SEP ":"
68 /* Some versions (1.3.79, 1.3.81) of Linux don't support SIOCSPGRP the way
69 gdbtk wants to use it... */
74 static void null_routine
PARAMS ((int));
75 static void gdbtk_flush
PARAMS ((FILE *));
76 static void gdbtk_fputs
PARAMS ((const char *, FILE *));
77 static int gdbtk_query
PARAMS ((const char *, va_list));
78 static char *gdbtk_readline
PARAMS ((char *));
79 static void gdbtk_init
PARAMS ((char *));
80 static void tk_command_loop
PARAMS ((void));
81 static void gdbtk_call_command
PARAMS ((struct cmd_list_element
*, char *, int));
82 static int gdbtk_wait
PARAMS ((int, struct target_waitstatus
*));
83 static void x_event
PARAMS ((int));
84 static void gdbtk_interactive
PARAMS ((void));
85 static void cleanup_init
PARAMS ((int));
86 static void tk_command
PARAMS ((char *, int));
87 static int gdb_disassemble
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
88 static int compare_lines
PARAMS ((const PTR
, const PTR
));
89 static int gdbtk_dis_asm_read_memory
PARAMS ((bfd_vma
, bfd_byte
*, int, disassemble_info
*));
90 static int gdb_path_conv
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
91 static int gdb_stop
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
92 static int gdb_listfiles
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
93 static int call_wrapper
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
94 static int gdb_cmd
PARAMS ((ClientData
, Tcl_Interp
*, int, char *argv
[]));
95 static int gdb_fetch_registers
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
96 static void gdbtk_readline_end
PARAMS ((void));
97 static int gdb_changed_register_list
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
98 static void register_changed_p
PARAMS ((int, void *));
99 static int gdb_get_breakpoint_list
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
100 static int gdb_get_breakpoint_info
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
101 static void breakpoint_notify
PARAMS ((struct breakpoint
*, const char *));
102 static void gdbtk_create_breakpoint
PARAMS ((struct breakpoint
*));
103 static void gdbtk_delete_breakpoint
PARAMS ((struct breakpoint
*));
104 static void gdbtk_modify_breakpoint
PARAMS ((struct breakpoint
*));
105 static int gdb_loc
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
106 static int gdb_eval
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
107 static int gdb_sourcelines
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
108 static int map_arg_registers
PARAMS ((int, char *[], void (*) (int, void *), void *));
109 static void get_register_name
PARAMS ((int, void *));
110 static int gdb_regnames
PARAMS ((ClientData
, Tcl_Interp
*, int, char *[]));
111 static void get_register
PARAMS ((int, void *));
113 /* Handle for TCL interpreter */
115 static Tcl_Interp
*interp
= NULL
;
117 static int x_fd
; /* X network socket */
119 /* This variable is true when the inferior is running. Although it's
120 possible to disable most input from widgets and thus prevent
121 attempts to do anything while the inferior is running, any commands
122 that get through - even a simple memory read - are Very Bad, and
123 may cause GDB to crash or behave strangely. So, this variable
124 provides an extra layer of defense. */
126 static int running_now
;
128 /* This variable determines where memory used for disassembly is read from.
129 If > 0, then disassembly comes from the exec file rather than the
130 target (which might be at the other end of a slow serial link). If
131 == 0 then disassembly comes from target. If < 0 disassembly is
132 automatically switched to the target if it's an inferior process,
133 otherwise the exec file is used. */
135 static int disassemble_from_exec
= -1;
139 /* Supply malloc calls for tcl/tk. We do not want to do this on
140 Windows, because Tcl_Alloc is probably in a DLL which will not call
141 the mmalloc routines. */
147 return xmalloc (size
);
151 Tcl_Realloc (ptr
, size
)
155 return xrealloc (ptr
, size
);
173 /* The following routines deal with stdout/stderr data, which is created by
174 {f}printf_{un}filtered and friends. gdbtk_fputs and gdbtk_flush are the
175 lowest level of these routines and capture all output from the rest of GDB.
176 Normally they present their data to tcl via callbacks to the following tcl
177 routines: gdbtk_tcl_fputs, gdbtk_tcl_fputs_error, and gdbtk_flush. These
178 in turn call tk routines to update the display.
180 Under some circumstances, you may want to collect the output so that it can
181 be returned as the value of a tcl procedure. This can be done by
182 surrounding the output routines with calls to start_saving_output and
183 finish_saving_output. The saved data can then be retrieved with
184 get_saved_output (but this must be done before the call to
185 finish_saving_output). */
187 /* Dynamic string header for stdout. */
189 static Tcl_DString
*result_ptr
;
196 /* Force immediate screen update */
198 Tcl_VarEval (interp
, "gdbtk_tcl_flush", NULL
);
203 gdbtk_fputs (ptr
, stream
)
208 Tcl_DStringAppend (result_ptr
, (char *)ptr
, -1);
213 Tcl_DStringInit (&str
);
215 Tcl_DStringAppend (&str
, "gdbtk_tcl_fputs", -1);
216 Tcl_DStringAppendElement (&str
, (char *)ptr
);
218 Tcl_Eval (interp
, Tcl_DStringValue (&str
));
219 Tcl_DStringFree (&str
);
224 gdbtk_query (query
, args
)
228 char buf
[200], *merge
[2];
232 vsprintf (buf
, query
, args
);
233 merge
[0] = "gdbtk_tcl_query";
235 command
= Tcl_Merge (2, merge
);
236 Tcl_Eval (interp
, command
);
239 val
= atol (interp
->result
);
245 #ifdef ANSI_PROTOTYPES
246 gdbtk_readline_begin (char *format
, ...)
248 gdbtk_readline_begin (va_alist
)
253 char buf
[200], *merge
[2];
256 #ifdef ANSI_PROTOTYPES
257 va_start (args
, format
);
261 format
= va_arg (args
, char *);
264 vsprintf (buf
, format
, args
);
265 merge
[0] = "gdbtk_tcl_readline_begin";
267 command
= Tcl_Merge (2, merge
);
268 Tcl_Eval (interp
, command
);
273 gdbtk_readline (prompt
)
280 merge
[0] = "gdbtk_tcl_readline";
282 command
= Tcl_Merge (2, merge
);
283 result
= Tcl_Eval (interp
, command
);
285 if (result
== TCL_OK
)
287 return (strdup (interp
-> result
));
291 gdbtk_fputs (interp
-> result
, gdb_stdout
);
292 gdbtk_fputs ("\n", gdb_stdout
);
298 gdbtk_readline_end ()
300 Tcl_Eval (interp
, "gdbtk_tcl_readline_end");
305 #ifdef ANSI_PROTOTYPES
306 dsprintf_append_element (Tcl_DString
*dsp
, char *format
, ...)
308 dsprintf_append_element (va_alist
)
315 #ifdef ANSI_PROTOTYPES
316 va_start (args
, format
);
322 dsp
= va_arg (args
, Tcl_DString
*);
323 format
= va_arg (args
, char *);
326 vsprintf (buf
, format
, args
);
328 Tcl_DStringAppendElement (dsp
, buf
);
332 gdb_path_conv (clientData
, interp
, argc
, argv
)
333 ClientData clientData
;
339 char pathname
[256], *ptr
;
341 error ("wrong # args");
342 cygwin32_conv_to_full_win32_path (argv
[1], pathname
);
343 for (ptr
= pathname
; *ptr
; ptr
++)
349 char *pathname
= argv
[1];
351 Tcl_DStringAppend (result_ptr
, pathname
, strlen(pathname
));
356 gdb_get_breakpoint_list (clientData
, interp
, argc
, argv
)
357 ClientData clientData
;
362 struct breakpoint
*b
;
363 extern struct breakpoint
*breakpoint_chain
;
366 error ("wrong # args");
368 for (b
= breakpoint_chain
; b
; b
= b
->next
)
369 if (b
->type
== bp_breakpoint
)
370 dsprintf_append_element (result_ptr
, "%d", b
->number
);
376 gdb_get_breakpoint_info (clientData
, interp
, argc
, argv
)
377 ClientData clientData
;
382 struct symtab_and_line sal
;
383 static char *bptypes
[] = {"breakpoint", "hardware breakpoint", "until",
384 "finish", "watchpoint", "hardware watchpoint",
385 "read watchpoint", "access watchpoint",
386 "longjmp", "longjmp resume", "step resume",
387 "through sigtramp", "watchpoint scope",
389 static char *bpdisp
[] = {"delete", "delstop", "disable", "donttouch"};
390 struct command_line
*cmd
;
392 struct breakpoint
*b
;
393 extern struct breakpoint
*breakpoint_chain
;
396 error ("wrong # args");
398 bpnum
= atoi (argv
[1]);
400 for (b
= breakpoint_chain
; b
; b
= b
->next
)
401 if (b
->number
== bpnum
)
404 if (!b
|| b
->type
!= bp_breakpoint
)
405 error ("Breakpoint #%d does not exist", bpnum
);
407 sal
= find_pc_line (b
->address
, 0);
409 Tcl_DStringAppendElement (result_ptr
, symtab_to_filename (sal
.symtab
));
410 dsprintf_append_element (result_ptr
, "%d", sal
.line
);
411 dsprintf_append_element (result_ptr
, "0x%lx", b
->address
);
412 Tcl_DStringAppendElement (result_ptr
, bptypes
[b
->type
]);
413 Tcl_DStringAppendElement (result_ptr
, b
->enable
== enabled
? "1" : "0");
414 Tcl_DStringAppendElement (result_ptr
, bpdisp
[b
->disposition
]);
415 dsprintf_append_element (result_ptr
, "%d", b
->silent
);
416 dsprintf_append_element (result_ptr
, "%d", b
->ignore_count
);
418 Tcl_DStringStartSublist (result_ptr
);
419 for (cmd
= b
->commands
; cmd
; cmd
= cmd
->next
)
420 Tcl_DStringAppendElement (result_ptr
, cmd
->line
);
421 Tcl_DStringEndSublist (result_ptr
);
423 Tcl_DStringAppendElement (result_ptr
, b
->cond_string
);
425 dsprintf_append_element (result_ptr
, "%d", b
->thread
);
426 dsprintf_append_element (result_ptr
, "%d", b
->hit_count
);
432 breakpoint_notify(b
, action
)
433 struct breakpoint
*b
;
438 struct symtab_and_line sal
;
440 if (b
->type
!= bp_breakpoint
)
443 /* We ensure that ACTION contains no special Tcl characters, so we
445 sal
= find_pc_line (b
->address
, 0);
446 sprintf (buf
, "gdbtk_tcl_breakpoint %s %d 0x%lx %d {%s}", action
, b
->number
,
447 (long)b
->address
, sal
.line
, symtab_to_filename (sal
.symtab
));
449 v
= Tcl_Eval (interp
, buf
);
453 gdbtk_fputs (interp
->result
, gdb_stdout
);
454 gdbtk_fputs ("\n", gdb_stdout
);
459 gdbtk_create_breakpoint(b
)
460 struct breakpoint
*b
;
462 breakpoint_notify (b
, "create");
466 gdbtk_delete_breakpoint(b
)
467 struct breakpoint
*b
;
469 breakpoint_notify (b
, "delete");
473 gdbtk_modify_breakpoint(b
)
474 struct breakpoint
*b
;
476 breakpoint_notify (b
, "modify");
479 /* This implements the TCL command `gdb_loc', which returns a list consisting
480 of the source and line number associated with the current pc. */
483 gdb_loc (clientData
, interp
, argc
, argv
)
484 ClientData clientData
;
490 struct symtab_and_line sal
;
496 pc
= selected_frame
? selected_frame
->pc
: stop_pc
;
497 sal
= find_pc_line (pc
, 0);
501 struct symtabs_and_lines sals
;
504 sals
= decode_line_spec (argv
[1], 1);
511 error ("Ambiguous line spec");
516 error ("wrong # args");
519 Tcl_DStringAppendElement (result_ptr
, sal
.symtab
->filename
);
521 Tcl_DStringAppendElement (result_ptr
, "");
523 find_pc_partial_function (pc
, &funcname
, NULL
, NULL
);
524 Tcl_DStringAppendElement (result_ptr
, funcname
);
526 filename
= symtab_to_filename (sal
.symtab
);
527 Tcl_DStringAppendElement (result_ptr
, filename
);
529 dsprintf_append_element (result_ptr
, "%d", sal
.line
); /* line number */
531 dsprintf_append_element (result_ptr
, "0x%s", paddr_nz(pc
)); /* PC in current frame */
533 dsprintf_append_element (result_ptr
, "0x%s", paddr_nz(stop_pc
)); /* Real PC */
538 /* This implements the TCL command `gdb_eval'. */
541 gdb_eval (clientData
, interp
, argc
, argv
)
542 ClientData clientData
;
547 struct expression
*expr
;
548 struct cleanup
*old_chain
;
552 error ("wrong # args");
554 expr
= parse_expression (argv
[1]);
556 old_chain
= make_cleanup (free_current_contents
, &expr
);
558 val
= evaluate_expression (expr
);
560 val_print (VALUE_TYPE (val
), VALUE_CONTENTS (val
), VALUE_ADDRESS (val
),
561 gdb_stdout
, 0, 0, 0, 0);
563 do_cleanups (old_chain
);
568 /* This implements the TCL command `gdb_sourcelines', which returns a list of
569 all of the lines containing executable code for the specified source file
570 (ie: lines where you can put breakpoints). */
573 gdb_sourcelines (clientData
, interp
, argc
, argv
)
574 ClientData clientData
;
579 struct symtab
*symtab
;
580 struct linetable_entry
*le
;
584 error ("wrong # args");
586 symtab
= lookup_symtab (argv
[1]);
589 error ("No such file");
591 /* If there's no linetable, or no entries, then we are done. */
593 if (!symtab
->linetable
594 || symtab
->linetable
->nitems
== 0)
596 Tcl_DStringAppendElement (result_ptr
, "");
600 le
= symtab
->linetable
->item
;
601 nlines
= symtab
->linetable
->nitems
;
603 for (;nlines
> 0; nlines
--, le
++)
605 /* If the pc of this line is the same as the pc of the next line, then
608 && le
->pc
== (le
+ 1)->pc
)
611 dsprintf_append_element (result_ptr
, "%d", le
->line
);
618 map_arg_registers (argc
, argv
, func
, argp
)
621 void (*func
) PARAMS ((int regnum
, void *argp
));
626 /* Note that the test for a valid register must include checking the
627 reg_names array because NUM_REGS may be allocated for the union of the
628 register sets within a family of related processors. In this case, the
629 trailing entries of reg_names will change depending upon the particular
630 processor being debugged. */
632 if (argc
== 0) /* No args, just do all the regs */
636 && reg_names
[regnum
] != NULL
637 && *reg_names
[regnum
] != '\000';
644 /* Else, list of register #s, just do listed regs */
645 for (; argc
> 0; argc
--, argv
++)
647 regnum
= atoi (*argv
);
651 && reg_names
[regnum
] != NULL
652 && *reg_names
[regnum
] != '\000')
655 error ("bad register number");
662 get_register_name (regnum
, argp
)
664 void *argp
; /* Ignored */
666 Tcl_DStringAppendElement (result_ptr
, reg_names
[regnum
]);
669 /* This implements the TCL command `gdb_regnames', which returns a list of
670 all of the register names. */
673 gdb_regnames (clientData
, interp
, argc
, argv
)
674 ClientData clientData
;
682 return map_arg_registers (argc
, argv
, get_register_name
, NULL
);
685 #ifndef REGISTER_CONVERTIBLE
686 #define REGISTER_CONVERTIBLE(x) (0 != 0)
689 #ifndef REGISTER_CONVERT_TO_VIRTUAL
690 #define REGISTER_CONVERT_TO_VIRTUAL(x, y, z, a)
693 #ifndef INVALID_FLOAT
694 #define INVALID_FLOAT(x, y) (0 != 0)
698 get_register (regnum
, fp
)
702 char raw_buffer
[MAX_REGISTER_RAW_SIZE
];
703 char virtual_buffer
[MAX_REGISTER_VIRTUAL_SIZE
];
704 int format
= (int)fp
;
706 if (read_relative_register_raw_bytes (regnum
, raw_buffer
))
708 Tcl_DStringAppendElement (result_ptr
, "Optimized out");
712 /* Convert raw data to virtual format if necessary. */
714 if (REGISTER_CONVERTIBLE (regnum
))
716 REGISTER_CONVERT_TO_VIRTUAL (regnum
, REGISTER_VIRTUAL_TYPE (regnum
),
717 raw_buffer
, virtual_buffer
);
720 memcpy (virtual_buffer
, raw_buffer
, REGISTER_VIRTUAL_SIZE (regnum
));
725 printf_filtered ("0x");
726 for (j
= 0; j
< REGISTER_RAW_SIZE (regnum
); j
++)
728 register int idx
= TARGET_BYTE_ORDER
== BIG_ENDIAN
? j
729 : REGISTER_RAW_SIZE (regnum
) - 1 - j
;
730 printf_filtered ("%02x", (unsigned char)raw_buffer
[idx
]);
734 val_print (REGISTER_VIRTUAL_TYPE (regnum
), virtual_buffer
, 0,
735 gdb_stdout
, format
, 1, 0, Val_pretty_default
);
737 Tcl_DStringAppend (result_ptr
, " ", -1);
741 gdb_fetch_registers (clientData
, interp
, argc
, argv
)
742 ClientData clientData
;
750 error ("wrong # args");
758 return map_arg_registers (argc
, argv
, get_register
, (void *) format
);
761 /* This contains the previous values of the registers, since the last call to
762 gdb_changed_register_list. */
764 static char old_regs
[REGISTER_BYTES
];
767 register_changed_p (regnum
, argp
)
769 void *argp
; /* Ignored */
771 char raw_buffer
[MAX_REGISTER_RAW_SIZE
];
773 if (read_relative_register_raw_bytes (regnum
, raw_buffer
))
776 if (memcmp (&old_regs
[REGISTER_BYTE (regnum
)], raw_buffer
,
777 REGISTER_RAW_SIZE (regnum
)) == 0)
780 /* Found a changed register. Save new value and return its number. */
782 memcpy (&old_regs
[REGISTER_BYTE (regnum
)], raw_buffer
,
783 REGISTER_RAW_SIZE (regnum
));
785 dsprintf_append_element (result_ptr
, "%d", regnum
);
789 gdb_changed_register_list (clientData
, interp
, argc
, argv
)
790 ClientData clientData
;
798 return map_arg_registers (argc
, argv
, register_changed_p
, NULL
);
801 /* This implements the TCL command `gdb_cmd', which sends its argument into
802 the GDB command scanner. */
805 gdb_cmd (clientData
, interp
, argc
, argv
)
806 ClientData clientData
;
812 error ("wrong # args");
817 execute_command (argv
[1], 1);
819 bpstat_do_actions (&stop_bpstat
);
824 /* Client of call_wrapper - this routine performs the actual call to
825 the client function. */
827 struct wrapped_call_args
838 struct wrapped_call_args
*args
;
840 args
->val
= (*args
->func
) (args
->func
, args
->interp
, args
->argc
, args
->argv
);
844 /* This routine acts as a top-level for all GDB code called by tcl/Tk. It
845 handles cleanups, and calls to return_to_top_level (usually via error).
846 This is necessary in order to prevent a longjmp out of the bowels of Tk,
847 possibly leaving things in a bad state. Since this routine can be called
848 recursively, it needs to save and restore the contents of the jmp_buf as
852 call_wrapper (clientData
, interp
, argc
, argv
)
853 ClientData clientData
;
858 struct wrapped_call_args wrapped_args
;
859 Tcl_DString result
, *old_result_ptr
;
861 Tcl_DStringInit (&result
);
862 old_result_ptr
= result_ptr
;
863 result_ptr
= &result
;
865 wrapped_args
.func
= (Tcl_CmdProc
*)clientData
;
866 wrapped_args
.interp
= interp
;
867 wrapped_args
.argc
= argc
;
868 wrapped_args
.argv
= argv
;
869 wrapped_args
.val
= 0;
871 if (!catch_errors (wrapped_call
, &wrapped_args
, "", RETURN_MASK_ALL
))
873 wrapped_args
.val
= TCL_ERROR
; /* Flag an error for TCL */
875 gdb_flush (gdb_stderr
); /* Flush error output */
877 gdb_flush (gdb_stdout
); /* Sometimes error output comes here as well */
879 /* In case of an error, we may need to force the GUI into idle
880 mode because gdbtk_call_command may have bombed out while in
881 the command routine. */
884 Tcl_Eval (interp
, "gdbtk_tcl_idle");
887 Tcl_DStringResult (interp
, &result
);
888 result_ptr
= old_result_ptr
;
890 return wrapped_args
.val
;
894 gdb_listfiles (clientData
, interp
, argc
, argv
)
895 ClientData clientData
;
900 struct objfile
*objfile
;
901 struct partial_symtab
*psymtab
;
902 struct symtab
*symtab
;
904 ALL_PSYMTABS (objfile
, psymtab
)
905 Tcl_DStringAppendElement (result_ptr
, psymtab
->filename
);
907 ALL_SYMTABS (objfile
, symtab
)
908 Tcl_DStringAppendElement (result_ptr
, symtab
->filename
);
914 gdb_stop (clientData
, interp
, argc
, argv
)
915 ClientData clientData
;
923 quit_flag
= 1; /* hope something sees this */
928 /* This implements the TCL command `gdb_disassemble'. */
931 gdbtk_dis_asm_read_memory (memaddr
, myaddr
, len
, info
)
935 disassemble_info
*info
;
937 extern struct target_ops exec_ops
;
941 res
= xfer_memory (memaddr
, myaddr
, len
, 0, &exec_ops
);
952 /* We need a different sort of line table from the normal one cuz we can't
953 depend upon implicit line-end pc's for lines. This is because of the
954 reordering we are about to do. */
956 struct my_line_entry
{
963 compare_lines (mle1p
, mle2p
)
967 struct my_line_entry
*mle1
, *mle2
;
970 mle1
= (struct my_line_entry
*) mle1p
;
971 mle2
= (struct my_line_entry
*) mle2p
;
973 val
= mle1
->line
- mle2
->line
;
978 return mle1
->start_pc
- mle2
->start_pc
;
982 gdb_disassemble (clientData
, interp
, argc
, argv
)
983 ClientData clientData
;
988 CORE_ADDR pc
, low
, high
;
989 int mixed_source_and_assembly
;
990 static disassemble_info di
;
991 static int di_initialized
;
993 if (! di_initialized
)
995 INIT_DISASSEMBLE_INFO_NO_ARCH (di
, gdb_stdout
,
996 (fprintf_ftype
) fprintf_unfiltered
);
997 di
.flavour
= bfd_target_unknown_flavour
;
998 di
.memory_error_func
= dis_asm_memory_error
;
999 di
.print_address_func
= dis_asm_print_address
;
1003 di
.mach
= tm_print_insn_info
.mach
;
1004 if (TARGET_BYTE_ORDER
== BIG_ENDIAN
)
1005 di
.endian
= BFD_ENDIAN_BIG
;
1007 di
.endian
= BFD_ENDIAN_LITTLE
;
1009 if (argc
!= 3 && argc
!= 4)
1010 error ("wrong # args");
1012 if (strcmp (argv
[1], "source") == 0)
1013 mixed_source_and_assembly
= 1;
1014 else if (strcmp (argv
[1], "nosource") == 0)
1015 mixed_source_and_assembly
= 0;
1017 error ("First arg must be 'source' or 'nosource'");
1019 low
= parse_and_eval_address (argv
[2]);
1023 if (find_pc_partial_function (low
, NULL
, &low
, &high
) == 0)
1024 error ("No function contains specified address");
1027 high
= parse_and_eval_address (argv
[3]);
1029 /* If disassemble_from_exec == -1, then we use the following heuristic to
1030 determine whether or not to do disassembly from target memory or from the
1033 If we're debugging a local process, read target memory, instead of the
1034 exec file. This makes disassembly of functions in shared libs work
1037 Else, we're debugging a remote process, and should disassemble from the
1038 exec file for speed. However, this is no good if the target modifies its
1039 code (for relocation, or whatever).
1042 if (disassemble_from_exec
== -1)
1043 if (strcmp (target_shortname
, "child") == 0
1044 || strcmp (target_shortname
, "procfs") == 0
1045 || strcmp (target_shortname
, "vxprocess") == 0)
1046 disassemble_from_exec
= 0; /* It's a child process, read inferior mem */
1048 disassemble_from_exec
= 1; /* It's remote, read the exec file */
1050 if (disassemble_from_exec
)
1051 di
.read_memory_func
= gdbtk_dis_asm_read_memory
;
1053 di
.read_memory_func
= dis_asm_read_memory
;
1055 /* If just doing straight assembly, all we need to do is disassemble
1056 everything between low and high. If doing mixed source/assembly, we've
1057 got a totally different path to follow. */
1059 if (mixed_source_and_assembly
)
1060 { /* Come here for mixed source/assembly */
1061 /* The idea here is to present a source-O-centric view of a function to
1062 the user. This means that things are presented in source order, with
1063 (possibly) out of order assembly immediately following. */
1064 struct symtab
*symtab
;
1065 struct linetable_entry
*le
;
1068 struct my_line_entry
*mle
;
1069 struct symtab_and_line sal
;
1074 symtab
= find_pc_symtab (low
); /* Assume symtab is valid for whole PC range */
1079 /* First, convert the linetable to a bunch of my_line_entry's. */
1081 le
= symtab
->linetable
->item
;
1082 nlines
= symtab
->linetable
->nitems
;
1087 mle
= (struct my_line_entry
*) alloca (nlines
* sizeof (struct my_line_entry
));
1091 /* Copy linetable entries for this function into our data structure, creating
1092 end_pc's and setting out_of_order as appropriate. */
1094 /* First, skip all the preceding functions. */
1096 for (i
= 0; i
< nlines
- 1 && le
[i
].pc
< low
; i
++) ;
1098 /* Now, copy all entries before the end of this function. */
1101 for (; i
< nlines
- 1 && le
[i
].pc
< high
; i
++)
1103 if (le
[i
].line
== le
[i
+ 1].line
1104 && le
[i
].pc
== le
[i
+ 1].pc
)
1105 continue; /* Ignore duplicates */
1107 mle
[newlines
].line
= le
[i
].line
;
1108 if (le
[i
].line
> le
[i
+ 1].line
)
1110 mle
[newlines
].start_pc
= le
[i
].pc
;
1111 mle
[newlines
].end_pc
= le
[i
+ 1].pc
;
1115 /* If we're on the last line, and it's part of the function, then we need to
1116 get the end pc in a special way. */
1121 mle
[newlines
].line
= le
[i
].line
;
1122 mle
[newlines
].start_pc
= le
[i
].pc
;
1123 sal
= find_pc_line (le
[i
].pc
, 0);
1124 mle
[newlines
].end_pc
= sal
.end
;
1128 /* Now, sort mle by line #s (and, then by addresses within lines). */
1131 qsort (mle
, newlines
, sizeof (struct my_line_entry
), compare_lines
);
1133 /* Now, for each line entry, emit the specified lines (unless they have been
1134 emitted before), followed by the assembly code for that line. */
1136 next_line
= 0; /* Force out first line */
1137 for (i
= 0; i
< newlines
; i
++)
1139 /* Print out everything from next_line to the current line. */
1141 if (mle
[i
].line
>= next_line
)
1144 print_source_lines (symtab
, next_line
, mle
[i
].line
+ 1, 0);
1146 print_source_lines (symtab
, mle
[i
].line
, mle
[i
].line
+ 1, 0);
1148 next_line
= mle
[i
].line
+ 1;
1151 for (pc
= mle
[i
].start_pc
; pc
< mle
[i
].end_pc
; )
1154 fputs_unfiltered (" ", gdb_stdout
);
1155 print_address (pc
, gdb_stdout
);
1156 fputs_unfiltered (":\t ", gdb_stdout
);
1157 pc
+= (*tm_print_insn
) (pc
, &di
);
1158 fputs_unfiltered ("\n", gdb_stdout
);
1165 for (pc
= low
; pc
< high
; )
1168 fputs_unfiltered (" ", gdb_stdout
);
1169 print_address (pc
, gdb_stdout
);
1170 fputs_unfiltered (":\t ", gdb_stdout
);
1171 pc
+= (*tm_print_insn
) (pc
, &di
);
1172 fputs_unfiltered ("\n", gdb_stdout
);
1176 gdb_flush (gdb_stdout
);
1182 tk_command (cmd
, from_tty
)
1188 struct cleanup
*old_chain
;
1190 /* Catch case of no argument, since this will make the tcl interpreter dump core. */
1192 error_no_arg ("tcl command to interpret");
1194 retval
= Tcl_Eval (interp
, cmd
);
1196 result
= strdup (interp
->result
);
1198 old_chain
= make_cleanup (free
, result
);
1200 if (retval
!= TCL_OK
)
1203 printf_unfiltered ("%s\n", result
);
1205 do_cleanups (old_chain
);
1209 cleanup_init (ignored
)
1213 Tcl_DeleteInterp (interp
);
1217 /* Come here during long calculations to check for GUI events. Usually invoked
1218 via the QUIT macro. */
1221 gdbtk_interactive ()
1223 /* Tk_DoOneEvent (TK_DONT_WAIT|TK_IDLE_EVENTS); */
1226 /* Come here when there is activity on the X file descriptor. */
1232 /* Process pending events */
1234 while (Tcl_DoOneEvent (TCL_DONT_WAIT
|TCL_ALL_EVENTS
) != 0);
1238 gdbtk_wait (pid
, ourstatus
)
1240 struct target_waitstatus
*ourstatus
;
1242 struct sigaction action
;
1243 static sigset_t nullsigmask
= {0};
1246 /* Needed for SunOS 4.1.x */
1247 #define SA_RESTART 0
1250 action
.sa_handler
= x_event
;
1251 action
.sa_mask
= nullsigmask
;
1252 action
.sa_flags
= SA_RESTART
;
1254 sigaction(SIGIO
, &action
, NULL
);
1257 pid
= target_wait (pid
, ourstatus
);
1259 action
.sa_handler
= SIG_IGN
;
1261 sigaction(SIGIO
, &action
, NULL
);
1267 /* This is called from execute_command, and provides a wrapper around
1268 various command routines in a place where both protocol messages and
1269 user input both flow through. Mostly this is used for indicating whether
1270 the target process is running or not.
1274 gdbtk_call_command (cmdblk
, arg
, from_tty
)
1275 struct cmd_list_element
*cmdblk
;
1280 if (cmdblk
->class == class_run
)
1283 Tcl_Eval (interp
, "gdbtk_tcl_busy");
1284 (*cmdblk
->function
.cfunc
)(arg
, from_tty
);
1286 Tcl_Eval (interp
, "gdbtk_tcl_idle");
1289 (*cmdblk
->function
.cfunc
)(arg
, from_tty
);
1292 /* This function is called instead of gdb's internal command loop. This is the
1293 last chance to do anything before entering the main Tk event loop. */
1298 extern GDB_FILE
*instream
;
1300 /* We no longer want to use stdin as the command input stream */
1302 Tcl_Eval (interp
, "gdbtk_tcl_preloop");
1307 gdbtk_init ( argv0
)
1310 struct cleanup
*old_chain
;
1311 char *lib
, *gdbtk_lib
, gdbtk_lib_tmp
[1024],gdbtk_file
[128];
1313 struct sigaction action
;
1314 static sigset_t nullsigmask
= {0};
1316 struct ide_event_handle
*h
;
1321 /* If there is no DISPLAY environment variable, Tk_Init below will fail,
1322 causing gdb to abort. If instead we simply return here, gdb will
1323 gracefully degrade to using the command line interface. */
1326 if (getenv ("DISPLAY") == NULL
)
1330 old_chain
= make_cleanup (cleanup_init
, 0);
1332 /* First init tcl and tk. */
1333 Tcl_FindExecutable (argv0
);
1334 interp
= Tcl_CreateInterp ();
1337 error ("Tcl_CreateInterp failed");
1339 if (Tcl_Init(interp
) != TCL_OK
)
1340 error ("Tcl_Init failed: %s", interp
->result
);
1342 if (Tk_Init(interp
) != TCL_OK
)
1343 error ("Tk_Init failed: %s", interp
->result
);
1345 if (Itcl_Init(interp
) == TCL_ERROR
)
1346 error ("Itcl_Init failed: %s", interp
->result
);
1348 if (Tix_Init(interp
) != TCL_OK
)
1349 error ("Tix_Init failed: %s", interp
->result
);
1352 /* Initialize the Paths variable.
1353 if (ide_initialize_paths (interp, "gdb") != TCL_OK)
1356 /* Find the directory where we expect to find idemanager. We ignore
1357 errors since it doesn't really matter if this fails. */
1358 libexecdir
= Tcl_GetVar2 (interp
, "Paths", "libexecdir", TCL_GLOBAL_ONLY
);
1362 h
= ide_event_init_client (&errmsg
, libexecdir
);
1365 Tcl_AppendResult (interp
, "can't initialize event system: ", errmsg
,
1367 fprintf(stderr
, "WARNING: ide_event_init_client failed: %s\n", interp
->result
);
1371 if (ide_create_tclevent_command (interp
, h
) != TCL_OK
)
1372 error ("ide_create_tclevent_command failed: %s", interp
->result
);
1373 if (ide_create_edit_command (interp
, h
) != TCL_OK
)
1374 error ("ide_create_edit_command failed: %s", interp
->result
);
1376 if (ide_create_property_command (interp
, h
) != TCL_OK
)
1377 error ("ide_create_property_command failed: %s", interp
->result
);
1380 if (ide_initialize (interp, "gdb") != TCL_OK)
1381 error ("ide_initialize failed: %s", interp->result);
1384 Tcl_SetVar (interp
, "GDBTK_IDE", "1", 0);
1386 Tcl_SetVar (interp
, "GDBTK_IDE", "0", 0);
1389 Tcl_CreateCommand (interp
, "gdb_cmd", call_wrapper
, gdb_cmd
, NULL
);
1390 Tcl_CreateCommand (interp
, "gdb_loc", call_wrapper
, gdb_loc
, NULL
);
1391 Tcl_CreateCommand (interp
, "gdb_path_conv", call_wrapper
, gdb_path_conv
, NULL
);
1392 Tcl_CreateCommand (interp
, "gdb_sourcelines", call_wrapper
, gdb_sourcelines
,
1394 Tcl_CreateCommand (interp
, "gdb_listfiles", call_wrapper
, gdb_listfiles
,
1396 Tcl_CreateCommand (interp
, "gdb_stop", call_wrapper
, gdb_stop
, NULL
);
1397 Tcl_CreateCommand (interp
, "gdb_regnames", call_wrapper
, gdb_regnames
, NULL
);
1398 Tcl_CreateCommand (interp
, "gdb_fetch_registers", call_wrapper
,
1399 gdb_fetch_registers
, NULL
);
1400 Tcl_CreateCommand (interp
, "gdb_changed_register_list", call_wrapper
,
1401 gdb_changed_register_list
, NULL
);
1402 Tcl_CreateCommand (interp
, "gdb_disassemble", call_wrapper
,
1403 gdb_disassemble
, NULL
);
1404 Tcl_CreateCommand (interp
, "gdb_eval", call_wrapper
, gdb_eval
, NULL
);
1405 Tcl_CreateCommand (interp
, "gdb_get_breakpoint_list", call_wrapper
,
1406 gdb_get_breakpoint_list
, NULL
);
1407 Tcl_CreateCommand (interp
, "gdb_get_breakpoint_info", call_wrapper
,
1408 gdb_get_breakpoint_info
, NULL
);
1410 command_loop_hook
= tk_command_loop
;
1411 print_frame_info_listing_hook
=
1412 (void (*) PARAMS ((struct symtab
*, int, int, int))) null_routine
;
1413 query_hook
= gdbtk_query
;
1414 flush_hook
= gdbtk_flush
;
1415 create_breakpoint_hook
= gdbtk_create_breakpoint
;
1416 delete_breakpoint_hook
= gdbtk_delete_breakpoint
;
1417 modify_breakpoint_hook
= gdbtk_modify_breakpoint
;
1418 interactive_hook
= gdbtk_interactive
;
1419 target_wait_hook
= gdbtk_wait
;
1420 call_command_hook
= gdbtk_call_command
;
1421 readline_begin_hook
= gdbtk_readline_begin
;
1422 readline_hook
= gdbtk_readline
;
1423 readline_end_hook
= gdbtk_readline_end
;
1425 /* Get the file descriptor for the X server */
1427 x_fd
= ConnectionNumber (Tk_Display (Tk_MainWindow (interp
)));
1429 /* Setup for I/O interrupts */
1431 action
.sa_mask
= nullsigmask
;
1432 action
.sa_flags
= 0;
1433 action
.sa_handler
= SIG_IGN
;
1435 sigaction(SIGIO
, &action
, NULL
);
1440 if (ioctl (x_fd
, FIOASYNC
, &i
))
1441 perror_with_name ("gdbtk_init: ioctl FIOASYNC failed");
1445 if (ioctl (x_fd
, SIOCSPGRP
, &i
))
1446 perror_with_name ("gdbtk_init: ioctl SIOCSPGRP failed");
1451 if (fcntl (x_fd
, F_SETOWN
, i
))
1452 perror_with_name ("gdbtk_init: fcntl F_SETOWN failed");
1453 #endif /* F_SETOWN */
1454 #endif /* !SIOCSPGRP */
1457 if (ioctl (x_fd
, I_SETSIG
, S_INPUT
|S_RDNORM
) < 0)
1458 perror_with_name ("gdbtk_init: ioctl I_SETSIG failed");
1461 #endif /* ifndef FIOASYNC */
1463 add_com ("tk", class_obscure
, tk_command
,
1464 "Send a command directly into tk.");
1466 Tcl_LinkVar (interp
, "disassemble-from-exec", (char *)&disassemble_from_exec
,
1469 /* find the gdb tcl library and source main.tcl */
1471 gdbtk_lib
= getenv ("GDBTK_LIBRARY");
1473 if (access ("gdbtcl/main.tcl", R_OK
) == 0)
1474 gdbtk_lib
= "gdbtcl";
1476 gdbtk_lib
= GDBTK_LIBRARY
;
1478 strcpy (gdbtk_lib_tmp
, gdbtk_lib
);
1480 /* see if GDBTK_LIBRARY is a path list */
1481 lib
= strtok (gdbtk_lib_tmp
, GDBTK_PATH_SEP
);
1484 if (Tcl_VarEval (interp
, "lappend auto_path ", lib
, NULL
) != TCL_OK
)
1486 fputs_unfiltered (Tcl_GetVar (interp
, "errorInfo", 0), gdb_stderr
);
1491 strcpy (gdbtk_file
, lib
);
1492 strcat (gdbtk_file
, "/main.tcl");
1493 if (access (gdbtk_file
, R_OK
) == 0)
1496 Tcl_SetVar (interp
, "GDBTK_LIBRARY", lib
, 0);
1500 while ((lib
= strtok (NULL
, ":")) != NULL
);
1504 fputs_unfiltered_hook
= NULL
; /* Force errors to stdout/stderr */
1505 if (getenv("GDBTK_LIBRARY"))
1507 fprintf_unfiltered (stderr
, "Unable to find main.tcl in %s\n",getenv("GDBTK_LIBRARY"));
1508 fprintf_unfiltered (stderr
,
1509 "Please set GDBTK_LIBRARY to a path that includes the GDB tcl files.\n");
1513 fprintf_unfiltered (stderr
, "Unable to find main.tcl in %s\n", GDBTK_LIBRARY
);
1514 fprintf_unfiltered (stderr
, "You might want to set GDBTK_LIBRARY\n");
1519 /* Defer setup of fputs_unfiltered_hook to near the end so that error messages
1520 prior to this point go to stdout/stderr. */
1522 fputs_unfiltered_hook
= gdbtk_fputs
;
1524 if (Tcl_EvalFile (interp
, gdbtk_file
) != TCL_OK
)
1526 fputs_unfiltered_hook
= NULL
; /* Force errors to stdout/stderr */
1528 fprintf_unfiltered (stderr
, "%s:%d: %s\n", gdbtk_file
,
1529 interp
->errorLine
, interp
->result
);
1531 fputs_unfiltered ("Stack trace:\n", gdb_stderr
);
1532 fputs_unfiltered (Tcl_GetVar (interp
, "errorInfo", 0), gdb_stderr
);
1536 discard_cleanups (old_chain
);
1539 /* Come here during initialize_all_files () */
1542 _initialize_gdbtk ()
1546 /* Tell the rest of the world that Gdbtk is now set up. */
1548 init_ui_hook
= gdbtk_init
;