* config/monitor.exp: Detect the "Couldn't establish connection"
[deliverable/binutils-gdb.git] / gdb / gdbtk.c
CommitLineData
4604b34c 1/* Tcl/Tk interface routines.
1a57cd09 2 Copyright 1994, 1995, 1996 Free Software Foundation, Inc.
4604b34c
SG
3
4 Written by Stu Grossman <grossman@cygnus.com> of Cygnus Support.
754e5da2
SG
5
6This file is part of GDB.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
6c9638b4 20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
754e5da2
SG
21
22#include "defs.h"
23#include "symtab.h"
24#include "inferior.h"
25#include "command.h"
26#include "bfd.h"
27#include "symfile.h"
28#include "objfiles.h"
29#include "target.h"
754e5da2
SG
30#include <tcl.h>
31#include <tk.h>
73d3dbd4 32#ifdef ANSI_PROTOTYPES
85c613aa
C
33#include <stdarg.h>
34#else
cd2df226 35#include <varargs.h>
85c613aa 36#endif
cd2df226
SG
37#include <signal.h>
38#include <fcntl.h>
8532893d 39#include <unistd.h>
86db943c
SG
40#include <setjmp.h>
41#include "top.h"
736a82e7 42#include <sys/ioctl.h>
2b576293 43#include "gdb_string.h"
09722039 44#include "dis-asm.h"
6131622e
SG
45#include <stdio.h>
46#include "gdbcmd.h"
736a82e7
SG
47
48#ifndef FIOASYNC
546b8ca7
SG
49#include <sys/stropts.h>
50#endif
754e5da2 51
8b3f9ed6 52/* Some versions (1.3.79, 1.3.81) of Linux don't support SIOCSPGRP the way
3f37b696 53 gdbtk wants to use it... */
8b3f9ed6
MM
54#ifdef __linux__
55#undef SIOCSPGRP
56#endif
57
b607efe7
FF
58static void null_routine PARAMS ((int));
59static void gdbtk_flush PARAMS ((FILE *));
60static void gdbtk_fputs PARAMS ((const char *, FILE *));
61static int gdbtk_query PARAMS ((const char *, va_list));
62static char *gdbtk_readline PARAMS ((char *));
63static void gdbtk_init PARAMS ((void));
64static void tk_command_loop PARAMS ((void));
65static void gdbtk_call_command PARAMS ((struct cmd_list_element *, char *, int));
66static int gdbtk_wait PARAMS ((int, struct target_waitstatus *));
67static void x_event PARAMS ((int));
68static void gdbtk_interactive PARAMS ((void));
69static void cleanup_init PARAMS ((int));
70static void tk_command PARAMS ((char *, int));
71static int gdb_disassemble PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
72static int compare_lines PARAMS ((const PTR, const PTR));
73static int gdbtk_dis_asm_read_memory PARAMS ((bfd_vma, bfd_byte *, int, disassemble_info *));
74static int gdb_stop PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
75static int gdb_listfiles PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
76static int call_wrapper PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
77static int gdb_cmd PARAMS ((ClientData, Tcl_Interp *, int, char *argv[]));
78static int gdb_fetch_registers PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
79static void gdbtk_readline_end PARAMS ((void));
80static int gdb_changed_register_list PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
81static void register_changed_p PARAMS ((int, void *));
82static int gdb_get_breakpoint_list PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
83static int gdb_get_breakpoint_info PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
84static void breakpoint_notify PARAMS ((struct breakpoint *, const char *));
85static void gdbtk_create_breakpoint PARAMS ((struct breakpoint *));
86static void gdbtk_delete_breakpoint PARAMS ((struct breakpoint *));
87static void gdbtk_modify_breakpoint PARAMS ((struct breakpoint *));
88static int gdb_loc PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
89static int gdb_eval PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
90static int gdb_sourcelines PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
91static int map_arg_registers PARAMS ((int, char *[], void (*) (int, void *), void *));
92static void get_register_name PARAMS ((int, void *));
93static int gdb_regnames PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
94static void get_register PARAMS ((int, void *));
95
754e5da2 96/* Handle for TCL interpreter */
fda6fadc 97
754e5da2
SG
98static Tcl_Interp *interp = NULL;
99
479f0f18
SG
100static int x_fd; /* X network socket */
101
fda6fadc
SS
102/* This variable is true when the inferior is running. Although it's
103 possible to disable most input from widgets and thus prevent
104 attempts to do anything while the inferior is running, any commands
105 that get through - even a simple memory read - are Very Bad, and
106 may cause GDB to crash or behave strangely. So, this variable
107 provides an extra layer of defense. */
09722039 108
fda6fadc
SS
109static int running_now;
110
111/* This variable determines where memory used for disassembly is read from.
112 If > 0, then disassembly comes from the exec file rather than the
113 target (which might be at the other end of a slow serial link). If
114 == 0 then disassembly comes from target. If < 0 disassembly is
115 automatically switched to the target if it's an inferior process,
116 otherwise the exec file is used. */
09722039
SG
117
118static int disassemble_from_exec = -1;
119
8c19daa1
SG
120/* Supply malloc calls for tcl/tk. */
121
122char *
a5a6e3bd 123Tcl_Alloc (size)
8c19daa1
SG
124 unsigned int size;
125{
126 return xmalloc (size);
127}
128
129char *
130Tcl_Realloc (ptr, size)
131 char *ptr;
132 unsigned int size;
133{
134 return xrealloc (ptr, size);
135}
136
137void
138Tcl_Free(ptr)
139 char *ptr;
140{
141 free (ptr);
142}
143
754e5da2
SG
144static void
145null_routine(arg)
146 int arg;
147{
148}
149
546b8ca7
SG
150/* The following routines deal with stdout/stderr data, which is created by
151 {f}printf_{un}filtered and friends. gdbtk_fputs and gdbtk_flush are the
152 lowest level of these routines and capture all output from the rest of GDB.
153 Normally they present their data to tcl via callbacks to the following tcl
154 routines: gdbtk_tcl_fputs, gdbtk_tcl_fputs_error, and gdbtk_flush. These
155 in turn call tk routines to update the display.
86db943c 156
546b8ca7
SG
157 Under some circumstances, you may want to collect the output so that it can
158 be returned as the value of a tcl procedure. This can be done by
159 surrounding the output routines with calls to start_saving_output and
160 finish_saving_output. The saved data can then be retrieved with
161 get_saved_output (but this must be done before the call to
162 finish_saving_output). */
86db943c 163
546b8ca7 164/* Dynamic string header for stdout. */
86db943c 165
6131622e 166static Tcl_DString *result_ptr;
754e5da2 167\f
754e5da2
SG
168static void
169gdbtk_flush (stream)
170 FILE *stream;
171{
6131622e 172#if 0
86db943c
SG
173 /* Force immediate screen update */
174
754e5da2 175 Tcl_VarEval (interp, "gdbtk_tcl_flush", NULL);
6131622e 176#endif
754e5da2
SG
177}
178
8532893d 179static void
86db943c 180gdbtk_fputs (ptr, stream)
8532893d 181 const char *ptr;
86db943c 182 FILE *stream;
8532893d 183{
fda6fadc 184
6131622e 185 if (result_ptr)
45f90c50 186 Tcl_DStringAppend (result_ptr, (char *)ptr, -1);
6131622e 187 else
86db943c 188 {
6131622e 189 Tcl_DString str;
86db943c 190
6131622e 191 Tcl_DStringInit (&str);
8532893d 192
6131622e 193 Tcl_DStringAppend (&str, "gdbtk_tcl_fputs", -1);
45f90c50 194 Tcl_DStringAppendElement (&str, (char *)ptr);
8532893d 195
6131622e
SG
196 Tcl_Eval (interp, Tcl_DStringValue (&str));
197 Tcl_DStringFree (&str);
198 }
8532893d
SG
199}
200
754e5da2 201static int
85c613aa 202gdbtk_query (query, args)
b607efe7 203 const char *query;
754e5da2
SG
204 va_list args;
205{
4e327047
TT
206 char buf[200], *merge[2];
207 char *command;
754e5da2
SG
208 long val;
209
6131622e 210 vsprintf (buf, query, args);
4e327047
TT
211 merge[0] = "gdbtk_tcl_query";
212 merge[1] = buf;
213 command = Tcl_Merge (2, merge);
214 Tcl_Eval (interp, command);
215 free (command);
754e5da2
SG
216
217 val = atol (interp->result);
218 return val;
219}
41756e56
FF
220
221/* VARARGS */
222static void
223#ifdef ANSI_PROTOTYPES
224gdbtk_readline_begin (char *format, ...)
225#else
226gdbtk_readline_begin (va_alist)
227 va_dcl
228#endif
229{
230 va_list args;
231 char buf[200], *merge[2];
232 char *command;
233
234#ifdef ANSI_PROTOTYPES
235 va_start (args, format);
236#else
237 char *format;
238 va_start (args);
239 format = va_arg (args, char *);
240#endif
241
242 vsprintf (buf, format, args);
243 merge[0] = "gdbtk_tcl_readline_begin";
244 merge[1] = buf;
245 command = Tcl_Merge (2, merge);
246 Tcl_Eval (interp, command);
247 free (command);
248}
249
250static char *
251gdbtk_readline (prompt)
252 char *prompt;
253{
254 char *merge[2];
255 char *command;
bd45f82f 256 int result;
41756e56
FF
257
258 merge[0] = "gdbtk_tcl_readline";
259 merge[1] = prompt;
260 command = Tcl_Merge (2, merge);
bd45f82f
TT
261 result = Tcl_Eval (interp, command);
262 free (command);
263 if (result == TCL_OK)
41756e56
FF
264 {
265 return (strdup (interp -> result));
266 }
267 else
268 {
269 gdbtk_fputs (interp -> result, gdb_stdout);
270 gdbtk_fputs ("\n", gdb_stdout);
271 return (NULL);
272 }
273}
274
275static void
276gdbtk_readline_end ()
277{
278 Tcl_Eval (interp, "gdbtk_tcl_readline_end");
279}
280
754e5da2 281\f
6131622e 282static void
73d3dbd4 283#ifdef ANSI_PROTOTYPES
85c613aa
C
284dsprintf_append_element (Tcl_DString *dsp, char *format, ...)
285#else
6131622e
SG
286dsprintf_append_element (va_alist)
287 va_dcl
85c613aa 288#endif
6131622e
SG
289{
290 va_list args;
85c613aa
C
291 char buf[1024];
292
73d3dbd4 293#ifdef ANSI_PROTOTYPES
85c613aa
C
294 va_start (args, format);
295#else
6131622e
SG
296 Tcl_DString *dsp;
297 char *format;
6131622e
SG
298
299 va_start (args);
6131622e
SG
300 dsp = va_arg (args, Tcl_DString *);
301 format = va_arg (args, char *);
85c613aa 302#endif
6131622e
SG
303
304 vsprintf (buf, format, args);
305
306 Tcl_DStringAppendElement (dsp, buf);
307}
308
309static int
310gdb_get_breakpoint_list (clientData, interp, argc, argv)
311 ClientData clientData;
312 Tcl_Interp *interp;
313 int argc;
314 char *argv[];
315{
316 struct breakpoint *b;
317 extern struct breakpoint *breakpoint_chain;
318
319 if (argc != 1)
320 error ("wrong # args");
321
322 for (b = breakpoint_chain; b; b = b->next)
323 if (b->type == bp_breakpoint)
324 dsprintf_append_element (result_ptr, "%d", b->number);
325
326 return TCL_OK;
327}
328
329static int
330gdb_get_breakpoint_info (clientData, interp, argc, argv)
331 ClientData clientData;
332 Tcl_Interp *interp;
333 int argc;
334 char *argv[];
335{
336 struct symtab_and_line sal;
337 static char *bptypes[] = {"breakpoint", "hardware breakpoint", "until",
338 "finish", "watchpoint", "hardware watchpoint",
339 "read watchpoint", "access watchpoint",
340 "longjmp", "longjmp resume", "step resume",
341 "through sigtramp", "watchpoint scope",
342 "call dummy" };
343 static char *bpdisp[] = {"delete", "disable", "donttouch"};
344 struct command_line *cmd;
345 int bpnum;
346 struct breakpoint *b;
347 extern struct breakpoint *breakpoint_chain;
348
349 if (argc != 2)
350 error ("wrong # args");
351
352 bpnum = atoi (argv[1]);
353
354 for (b = breakpoint_chain; b; b = b->next)
355 if (b->number == bpnum)
356 break;
357
9468f8aa 358 if (!b || b->type != bp_breakpoint)
6131622e
SG
359 error ("Breakpoint #%d does not exist", bpnum);
360
6131622e
SG
361 sal = find_pc_line (b->address, 0);
362
363 Tcl_DStringAppendElement (result_ptr, symtab_to_filename (sal.symtab));
364 dsprintf_append_element (result_ptr, "%d", sal.line);
365 dsprintf_append_element (result_ptr, "0x%lx", b->address);
366 Tcl_DStringAppendElement (result_ptr, bptypes[b->type]);
367 Tcl_DStringAppendElement (result_ptr, b->enable == enabled ? "1" : "0");
368 Tcl_DStringAppendElement (result_ptr, bpdisp[b->disposition]);
369 dsprintf_append_element (result_ptr, "%d", b->silent);
370 dsprintf_append_element (result_ptr, "%d", b->ignore_count);
371
372 Tcl_DStringStartSublist (result_ptr);
373 for (cmd = b->commands; cmd; cmd = cmd->next)
374 Tcl_DStringAppendElement (result_ptr, cmd->line);
375 Tcl_DStringEndSublist (result_ptr);
376
377 Tcl_DStringAppendElement (result_ptr, b->cond_string);
378
379 dsprintf_append_element (result_ptr, "%d", b->thread);
380 dsprintf_append_element (result_ptr, "%d", b->hit_count);
381
382 return TCL_OK;
383}
384
754e5da2
SG
385static void
386breakpoint_notify(b, action)
387 struct breakpoint *b;
388 const char *action;
389{
6131622e 390 char buf[100];
754e5da2
SG
391 int v;
392
393 if (b->type != bp_breakpoint)
394 return;
395
4e327047
TT
396 /* We ensure that ACTION contains no special Tcl characters, so we
397 can do this. */
6131622e 398 sprintf (buf, "gdbtk_tcl_breakpoint %s %d", action, b->number);
754e5da2 399
6131622e 400 v = Tcl_Eval (interp, buf);
754e5da2
SG
401
402 if (v != TCL_OK)
403 {
546b8ca7
SG
404 gdbtk_fputs (interp->result, gdb_stdout);
405 gdbtk_fputs ("\n", gdb_stdout);
754e5da2 406 }
754e5da2
SG
407}
408
409static void
410gdbtk_create_breakpoint(b)
411 struct breakpoint *b;
412{
6131622e 413 breakpoint_notify (b, "create");
754e5da2
SG
414}
415
416static void
417gdbtk_delete_breakpoint(b)
418 struct breakpoint *b;
419{
6131622e 420 breakpoint_notify (b, "delete");
754e5da2
SG
421}
422
423static void
6131622e 424gdbtk_modify_breakpoint(b)
754e5da2
SG
425 struct breakpoint *b;
426{
6131622e 427 breakpoint_notify (b, "modify");
754e5da2
SG
428}
429\f
430/* This implements the TCL command `gdb_loc', which returns a list consisting
431 of the source and line number associated with the current pc. */
432
433static int
434gdb_loc (clientData, interp, argc, argv)
435 ClientData clientData;
436 Tcl_Interp *interp;
437 int argc;
438 char *argv[];
439{
440 char *filename;
754e5da2
SG
441 struct symtab_and_line sal;
442 char *funcname;
8532893d 443 CORE_ADDR pc;
754e5da2
SG
444
445 if (argc == 1)
446 {
1dfc8dfb 447 pc = selected_frame ? selected_frame->pc : stop_pc;
754e5da2
SG
448 sal = find_pc_line (pc, 0);
449 }
450 else if (argc == 2)
451 {
754e5da2 452 struct symtabs_and_lines sals;
8532893d 453 int nelts;
754e5da2
SG
454
455 sals = decode_line_spec (argv[1], 1);
456
8532893d
SG
457 nelts = sals.nelts;
458 sal = sals.sals[0];
459 free (sals.sals);
460
754e5da2 461 if (sals.nelts != 1)
6131622e 462 error ("Ambiguous line spec");
754e5da2 463
8532893d 464 pc = sal.pc;
754e5da2
SG
465 }
466 else
6131622e 467 error ("wrong # args");
754e5da2 468
754e5da2 469 if (sal.symtab)
6131622e 470 Tcl_DStringAppendElement (result_ptr, sal.symtab->filename);
754e5da2 471 else
6131622e 472 Tcl_DStringAppendElement (result_ptr, "");
8532893d
SG
473
474 find_pc_partial_function (pc, &funcname, NULL, NULL);
6131622e 475 Tcl_DStringAppendElement (result_ptr, funcname);
8532893d 476
637b1661 477 filename = symtab_to_filename (sal.symtab);
6131622e 478 Tcl_DStringAppendElement (result_ptr, filename);
8532893d 479
9468f8aa 480 dsprintf_append_element (result_ptr, "%d", sal.line); /* line number */
754e5da2 481
78b9b170 482 dsprintf_append_element (result_ptr, "0x%s", paddr_nz(pc)); /* PC */
8532893d 483
754e5da2
SG
484 return TCL_OK;
485}
486\f
09722039
SG
487/* This implements the TCL command `gdb_eval'. */
488
489static int
490gdb_eval (clientData, interp, argc, argv)
491 ClientData clientData;
492 Tcl_Interp *interp;
493 int argc;
494 char *argv[];
495{
496 struct expression *expr;
497 struct cleanup *old_chain;
498 value_ptr val;
499
500 if (argc != 2)
6131622e 501 error ("wrong # args");
09722039
SG
502
503 expr = parse_expression (argv[1]);
504
505 old_chain = make_cleanup (free_current_contents, &expr);
506
507 val = evaluate_expression (expr);
508
09722039
SG
509 val_print (VALUE_TYPE (val), VALUE_CONTENTS (val), VALUE_ADDRESS (val),
510 gdb_stdout, 0, 0, 0, 0);
09722039
SG
511
512 do_cleanups (old_chain);
513
514 return TCL_OK;
515}
516\f
5b21fb68
SG
517/* This implements the TCL command `gdb_sourcelines', which returns a list of
518 all of the lines containing executable code for the specified source file
519 (ie: lines where you can put breakpoints). */
520
521static int
522gdb_sourcelines (clientData, interp, argc, argv)
523 ClientData clientData;
524 Tcl_Interp *interp;
525 int argc;
526 char *argv[];
527{
528 struct symtab *symtab;
529 struct linetable_entry *le;
530 int nlines;
5b21fb68
SG
531
532 if (argc != 2)
6131622e 533 error ("wrong # args");
5b21fb68
SG
534
535 symtab = lookup_symtab (argv[1]);
536
537 if (!symtab)
6131622e 538 error ("No such file");
5b21fb68
SG
539
540 /* If there's no linetable, or no entries, then we are done. */
541
542 if (!symtab->linetable
543 || symtab->linetable->nitems == 0)
544 {
6131622e 545 Tcl_DStringAppendElement (result_ptr, "");
5b21fb68
SG
546 return TCL_OK;
547 }
548
549 le = symtab->linetable->item;
550 nlines = symtab->linetable->nitems;
551
552 for (;nlines > 0; nlines--, le++)
553 {
554 /* If the pc of this line is the same as the pc of the next line, then
555 just skip it. */
556 if (nlines > 1
557 && le->pc == (le + 1)->pc)
558 continue;
559
9468f8aa 560 dsprintf_append_element (result_ptr, "%d", le->line);
5b21fb68
SG
561 }
562
563 return TCL_OK;
564}
565\f
746d1df4
SG
566static int
567map_arg_registers (argc, argv, func, argp)
568 int argc;
569 char *argv[];
6131622e 570 void (*func) PARAMS ((int regnum, void *argp));
746d1df4
SG
571 void *argp;
572{
573 int regnum;
574
575 /* Note that the test for a valid register must include checking the
576 reg_names array because NUM_REGS may be allocated for the union of the
577 register sets within a family of related processors. In this case, the
578 trailing entries of reg_names will change depending upon the particular
579 processor being debugged. */
580
581 if (argc == 0) /* No args, just do all the regs */
582 {
583 for (regnum = 0;
584 regnum < NUM_REGS
585 && reg_names[regnum] != NULL
586 && *reg_names[regnum] != '\000';
587 regnum++)
588 func (regnum, argp);
589
590 return TCL_OK;
591 }
592
593 /* Else, list of register #s, just do listed regs */
594 for (; argc > 0; argc--, argv++)
595 {
596 regnum = atoi (*argv);
597
598 if (regnum >= 0
599 && regnum < NUM_REGS
600 && reg_names[regnum] != NULL
601 && *reg_names[regnum] != '\000')
602 func (regnum, argp);
603 else
6131622e 604 error ("bad register number");
746d1df4
SG
605 }
606
607 return TCL_OK;
608}
609
6131622e 610static void
746d1df4
SG
611get_register_name (regnum, argp)
612 int regnum;
613 void *argp; /* Ignored */
614{
6131622e 615 Tcl_DStringAppendElement (result_ptr, reg_names[regnum]);
746d1df4
SG
616}
617
5b21fb68
SG
618/* This implements the TCL command `gdb_regnames', which returns a list of
619 all of the register names. */
620
621static int
622gdb_regnames (clientData, interp, argc, argv)
623 ClientData clientData;
624 Tcl_Interp *interp;
625 int argc;
626 char *argv[];
627{
746d1df4
SG
628 argc--;
629 argv++;
630
b607efe7 631 return map_arg_registers (argc, argv, get_register_name, NULL);
746d1df4
SG
632}
633
746d1df4
SG
634#ifndef REGISTER_CONVERTIBLE
635#define REGISTER_CONVERTIBLE(x) (0 != 0)
636#endif
637
638#ifndef REGISTER_CONVERT_TO_VIRTUAL
639#define REGISTER_CONVERT_TO_VIRTUAL(x, y, z, a)
640#endif
641
642#ifndef INVALID_FLOAT
643#define INVALID_FLOAT(x, y) (0 != 0)
644#endif
645
6131622e 646static void
746d1df4 647get_register (regnum, fp)
6131622e 648 int regnum;
746d1df4
SG
649 void *fp;
650{
651 char raw_buffer[MAX_REGISTER_RAW_SIZE];
652 char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
653 int format = (int)fp;
654
655 if (read_relative_register_raw_bytes (regnum, raw_buffer))
656 {
6131622e 657 Tcl_DStringAppendElement (result_ptr, "Optimized out");
746d1df4
SG
658 return;
659 }
660
746d1df4
SG
661 /* Convert raw data to virtual format if necessary. */
662
663 if (REGISTER_CONVERTIBLE (regnum))
664 {
665 REGISTER_CONVERT_TO_VIRTUAL (regnum, REGISTER_VIRTUAL_TYPE (regnum),
666 raw_buffer, virtual_buffer);
667 }
668 else
669 memcpy (virtual_buffer, raw_buffer, REGISTER_VIRTUAL_SIZE (regnum));
670
3d9f68c0
FF
671 if (format == 'r')
672 {
673 int j;
674 printf_filtered ("0x");
675 for (j = 0; j < REGISTER_RAW_SIZE (regnum); j++)
676 {
677 register int idx = TARGET_BYTE_ORDER == BIG_ENDIAN ? j
678 : REGISTER_RAW_SIZE (regnum) - 1 - j;
679 printf_filtered ("%02x", (unsigned char)raw_buffer[idx]);
680 }
681 }
682 else
683 val_print (REGISTER_VIRTUAL_TYPE (regnum), virtual_buffer, 0,
684 gdb_stdout, format, 1, 0, Val_pretty_default);
746d1df4 685
6131622e 686 Tcl_DStringAppend (result_ptr, " ", -1);
746d1df4
SG
687}
688
689static int
690gdb_fetch_registers (clientData, interp, argc, argv)
691 ClientData clientData;
692 Tcl_Interp *interp;
693 int argc;
694 char *argv[];
695{
696 int format;
697
698 if (argc < 2)
6131622e 699 error ("wrong # args");
5b21fb68 700
746d1df4
SG
701 argc--;
702 argv++;
5b21fb68 703
746d1df4
SG
704 argc--;
705 format = **argv++;
706
b607efe7 707 return map_arg_registers (argc, argv, get_register, (void *) format);
746d1df4
SG
708}
709
710/* This contains the previous values of the registers, since the last call to
711 gdb_changed_register_list. */
712
713static char old_regs[REGISTER_BYTES];
714
6131622e 715static void
746d1df4 716register_changed_p (regnum, argp)
6131622e 717 int regnum;
746d1df4
SG
718 void *argp; /* Ignored */
719{
720 char raw_buffer[MAX_REGISTER_RAW_SIZE];
746d1df4
SG
721
722 if (read_relative_register_raw_bytes (regnum, raw_buffer))
723 return;
724
725 if (memcmp (&old_regs[REGISTER_BYTE (regnum)], raw_buffer,
726 REGISTER_RAW_SIZE (regnum)) == 0)
727 return;
728
fda6fadc 729 /* Found a changed register. Save new value and return its number. */
746d1df4
SG
730
731 memcpy (&old_regs[REGISTER_BYTE (regnum)], raw_buffer,
732 REGISTER_RAW_SIZE (regnum));
733
9468f8aa 734 dsprintf_append_element (result_ptr, "%d", regnum);
746d1df4
SG
735}
736
737static int
738gdb_changed_register_list (clientData, interp, argc, argv)
739 ClientData clientData;
740 Tcl_Interp *interp;
741 int argc;
742 char *argv[];
743{
746d1df4
SG
744 argc--;
745 argv++;
746
747 return map_arg_registers (argc, argv, register_changed_p, NULL);
5b21fb68
SG
748}
749\f
fda6fadc 750/* This implements the TCL command `gdb_cmd', which sends its argument into
754e5da2
SG
751 the GDB command scanner. */
752
753static int
754gdb_cmd (clientData, interp, argc, argv)
755 ClientData clientData;
756 Tcl_Interp *interp;
757 int argc;
758 char *argv[];
759{
754e5da2 760 if (argc != 2)
6131622e 761 error ("wrong # args");
754e5da2 762
fda6fadc
SS
763 if (running_now)
764 return TCL_OK;
765
86db943c 766 execute_command (argv[1], 1);
479f0f18 767
754e5da2 768 bpstat_do_actions (&stop_bpstat);
754e5da2 769
754e5da2
SG
770 return TCL_OK;
771}
772
86db943c
SG
773/* This routine acts as a top-level for all GDB code called by tcl/Tk. It
774 handles cleanups, and calls to return_to_top_level (usually via error).
775 This is necessary in order to prevent a longjmp out of the bowels of Tk,
776 possibly leaving things in a bad state. Since this routine can be called
777 recursively, it needs to save and restore the contents of the jmp_buf as
778 necessary. */
779
780static int
781call_wrapper (clientData, interp, argc, argv)
782 ClientData clientData;
783 Tcl_Interp *interp;
784 int argc;
785 char *argv[];
786{
787 int val;
788 struct cleanup *saved_cleanup_chain;
789 Tcl_CmdProc *func;
790 jmp_buf saved_error_return;
6131622e
SG
791 Tcl_DString result, *old_result_ptr;
792
793 Tcl_DStringInit (&result);
794 old_result_ptr = result_ptr;
795 result_ptr = &result;
86db943c
SG
796
797 func = (Tcl_CmdProc *)clientData;
798 memcpy (saved_error_return, error_return, sizeof (jmp_buf));
799
800 saved_cleanup_chain = save_cleanups ();
801
802 if (!setjmp (error_return))
803 val = func (clientData, interp, argc, argv);
804 else
805 {
806 val = TCL_ERROR; /* Flag an error for TCL */
807
86db943c
SG
808 gdb_flush (gdb_stderr); /* Flush error output */
809
09722039
SG
810 gdb_flush (gdb_stdout); /* Sometimes error output comes here as well */
811
fda6fadc
SS
812 /* In case of an error, we may need to force the GUI into idle
813 mode because gdbtk_call_command may have bombed out while in
814 the command routine. */
86db943c 815
40dffa42 816 running_now = 0;
4e327047 817 Tcl_Eval (interp, "gdbtk_tcl_idle");
86db943c
SG
818 }
819
820 do_cleanups (ALL_CLEANUPS);
821
822 restore_cleanups (saved_cleanup_chain);
823
824 memcpy (error_return, saved_error_return, sizeof (jmp_buf));
825
6131622e
SG
826 Tcl_DStringResult (interp, &result);
827 result_ptr = old_result_ptr;
828
86db943c
SG
829 return val;
830}
831
754e5da2
SG
832static int
833gdb_listfiles (clientData, interp, argc, argv)
834 ClientData clientData;
835 Tcl_Interp *interp;
836 int argc;
837 char *argv[];
838{
754e5da2
SG
839 struct objfile *objfile;
840 struct partial_symtab *psymtab;
546b8ca7 841 struct symtab *symtab;
754e5da2
SG
842
843 ALL_PSYMTABS (objfile, psymtab)
6131622e 844 Tcl_DStringAppendElement (result_ptr, psymtab->filename);
754e5da2 845
546b8ca7 846 ALL_SYMTABS (objfile, symtab)
6131622e 847 Tcl_DStringAppendElement (result_ptr, symtab->filename);
546b8ca7 848
754e5da2
SG
849 return TCL_OK;
850}
479f0f18
SG
851
852static int
853gdb_stop (clientData, interp, argc, argv)
854 ClientData clientData;
855 Tcl_Interp *interp;
856 int argc;
857 char *argv[];
858{
6c27841f 859 target_stop ();
546b8ca7
SG
860
861 return TCL_OK;
479f0f18 862}
09722039
SG
863\f
864/* This implements the TCL command `gdb_disassemble'. */
479f0f18 865
09722039
SG
866static int
867gdbtk_dis_asm_read_memory (memaddr, myaddr, len, info)
868 bfd_vma memaddr;
869 bfd_byte *myaddr;
870 int len;
871 disassemble_info *info;
872{
873 extern struct target_ops exec_ops;
874 int res;
875
876 errno = 0;
877 res = xfer_memory (memaddr, myaddr, len, 0, &exec_ops);
878
879 if (res == len)
880 return 0;
881 else
882 if (errno == 0)
883 return EIO;
884 else
885 return errno;
886}
887
888/* We need a different sort of line table from the normal one cuz we can't
889 depend upon implicit line-end pc's for lines. This is because of the
890 reordering we are about to do. */
891
892struct my_line_entry {
893 int line;
894 CORE_ADDR start_pc;
895 CORE_ADDR end_pc;
896};
897
898static int
899compare_lines (mle1p, mle2p)
900 const PTR mle1p;
901 const PTR mle2p;
902{
903 struct my_line_entry *mle1, *mle2;
904 int val;
905
906 mle1 = (struct my_line_entry *) mle1p;
907 mle2 = (struct my_line_entry *) mle2p;
908
909 val = mle1->line - mle2->line;
910
911 if (val != 0)
912 return val;
913
914 return mle1->start_pc - mle2->start_pc;
915}
916
917static int
918gdb_disassemble (clientData, interp, argc, argv)
919 ClientData clientData;
920 Tcl_Interp *interp;
921 int argc;
922 char *argv[];
923{
924 CORE_ADDR pc, low, high;
925 int mixed_source_and_assembly;
fc941258
DE
926 static disassemble_info di;
927 static int di_initialized;
928
929 if (! di_initialized)
930 {
91550191
SG
931 INIT_DISASSEMBLE_INFO_NO_ARCH (di, gdb_stdout,
932 (fprintf_ftype) fprintf_unfiltered);
caeec767 933 di.flavour = bfd_target_unknown_flavour;
fc941258
DE
934 di.memory_error_func = dis_asm_memory_error;
935 di.print_address_func = dis_asm_print_address;
936 di_initialized = 1;
937 }
09722039 938
91550191
SG
939 di.mach = tm_print_insn_info.mach;
940 if (TARGET_BYTE_ORDER == BIG_ENDIAN)
941 tm_print_insn_info.endian = BFD_ENDIAN_BIG;
942 else
943 tm_print_insn_info.endian = BFD_ENDIAN_LITTLE;
944
09722039 945 if (argc != 3 && argc != 4)
6131622e 946 error ("wrong # args");
09722039
SG
947
948 if (strcmp (argv[1], "source") == 0)
949 mixed_source_and_assembly = 1;
950 else if (strcmp (argv[1], "nosource") == 0)
951 mixed_source_and_assembly = 0;
952 else
6131622e 953 error ("First arg must be 'source' or 'nosource'");
09722039
SG
954
955 low = parse_and_eval_address (argv[2]);
956
957 if (argc == 3)
958 {
959 if (find_pc_partial_function (low, NULL, &low, &high) == 0)
6131622e 960 error ("No function contains specified address");
09722039
SG
961 }
962 else
963 high = parse_and_eval_address (argv[3]);
964
965 /* If disassemble_from_exec == -1, then we use the following heuristic to
966 determine whether or not to do disassembly from target memory or from the
967 exec file:
968
969 If we're debugging a local process, read target memory, instead of the
970 exec file. This makes disassembly of functions in shared libs work
971 correctly.
972
973 Else, we're debugging a remote process, and should disassemble from the
fda6fadc 974 exec file for speed. However, this is no good if the target modifies its
09722039
SG
975 code (for relocation, or whatever).
976 */
977
978 if (disassemble_from_exec == -1)
979 if (strcmp (target_shortname, "child") == 0
d7c4766c
SS
980 || strcmp (target_shortname, "procfs") == 0
981 || strcmp (target_shortname, "vxprocess") == 0)
09722039
SG
982 disassemble_from_exec = 0; /* It's a child process, read inferior mem */
983 else
984 disassemble_from_exec = 1; /* It's remote, read the exec file */
985
986 if (disassemble_from_exec)
a76ef70a
SG
987 di.read_memory_func = gdbtk_dis_asm_read_memory;
988 else
989 di.read_memory_func = dis_asm_read_memory;
09722039
SG
990
991 /* If just doing straight assembly, all we need to do is disassemble
992 everything between low and high. If doing mixed source/assembly, we've
993 got a totally different path to follow. */
994
995 if (mixed_source_and_assembly)
996 { /* Come here for mixed source/assembly */
997 /* The idea here is to present a source-O-centric view of a function to
998 the user. This means that things are presented in source order, with
999 (possibly) out of order assembly immediately following. */
1000 struct symtab *symtab;
1001 struct linetable_entry *le;
1002 int nlines;
c81a3fa9 1003 int newlines;
09722039
SG
1004 struct my_line_entry *mle;
1005 struct symtab_and_line sal;
1006 int i;
1007 int out_of_order;
c81a3fa9 1008 int next_line;
09722039
SG
1009
1010 symtab = find_pc_symtab (low); /* Assume symtab is valid for whole PC range */
1011
1012 if (!symtab)
1013 goto assembly_only;
1014
1015/* First, convert the linetable to a bunch of my_line_entry's. */
1016
1017 le = symtab->linetable->item;
1018 nlines = symtab->linetable->nitems;
1019
1020 if (nlines <= 0)
1021 goto assembly_only;
1022
1023 mle = (struct my_line_entry *) alloca (nlines * sizeof (struct my_line_entry));
1024
1025 out_of_order = 0;
1026
c81a3fa9
SG
1027/* Copy linetable entries for this function into our data structure, creating
1028 end_pc's and setting out_of_order as appropriate. */
1029
1030/* First, skip all the preceding functions. */
1031
1032 for (i = 0; i < nlines - 1 && le[i].pc < low; i++) ;
1033
1034/* Now, copy all entries before the end of this function. */
1035
1036 newlines = 0;
1037 for (; i < nlines - 1 && le[i].pc < high; i++)
09722039 1038 {
c81a3fa9
SG
1039 if (le[i].line == le[i + 1].line
1040 && le[i].pc == le[i + 1].pc)
1041 continue; /* Ignore duplicates */
1042
1043 mle[newlines].line = le[i].line;
09722039
SG
1044 if (le[i].line > le[i + 1].line)
1045 out_of_order = 1;
c81a3fa9
SG
1046 mle[newlines].start_pc = le[i].pc;
1047 mle[newlines].end_pc = le[i + 1].pc;
1048 newlines++;
09722039
SG
1049 }
1050
c81a3fa9
SG
1051/* If we're on the last line, and it's part of the function, then we need to
1052 get the end pc in a special way. */
1053
1054 if (i == nlines - 1
1055 && le[i].pc < high)
1056 {
1057 mle[newlines].line = le[i].line;
1058 mle[newlines].start_pc = le[i].pc;
1059 sal = find_pc_line (le[i].pc, 0);
1060 mle[newlines].end_pc = sal.end;
1061 newlines++;
1062 }
09722039
SG
1063
1064/* Now, sort mle by line #s (and, then by addresses within lines). */
1065
1066 if (out_of_order)
c81a3fa9 1067 qsort (mle, newlines, sizeof (struct my_line_entry), compare_lines);
09722039
SG
1068
1069/* Now, for each line entry, emit the specified lines (unless they have been
1070 emitted before), followed by the assembly code for that line. */
1071
c81a3fa9
SG
1072 next_line = 0; /* Force out first line */
1073 for (i = 0; i < newlines; i++)
09722039 1074 {
c81a3fa9
SG
1075/* Print out everything from next_line to the current line. */
1076
1077 if (mle[i].line >= next_line)
09722039 1078 {
c81a3fa9
SG
1079 if (next_line != 0)
1080 print_source_lines (symtab, next_line, mle[i].line + 1, 0);
09722039 1081 else
c81a3fa9
SG
1082 print_source_lines (symtab, mle[i].line, mle[i].line + 1, 0);
1083
1084 next_line = mle[i].line + 1;
09722039 1085 }
c81a3fa9 1086
09722039
SG
1087 for (pc = mle[i].start_pc; pc < mle[i].end_pc; )
1088 {
1089 QUIT;
1090 fputs_unfiltered (" ", gdb_stdout);
1091 print_address (pc, gdb_stdout);
1092 fputs_unfiltered (":\t ", gdb_stdout);
d039851f 1093 pc += (*tm_print_insn) (pc, &di);
09722039
SG
1094 fputs_unfiltered ("\n", gdb_stdout);
1095 }
1096 }
1097 }
1098 else
1099 {
1100assembly_only:
1101 for (pc = low; pc < high; )
1102 {
1103 QUIT;
1104 fputs_unfiltered (" ", gdb_stdout);
1105 print_address (pc, gdb_stdout);
1106 fputs_unfiltered (":\t ", gdb_stdout);
d039851f 1107 pc += (*tm_print_insn) (pc, &di);
09722039
SG
1108 fputs_unfiltered ("\n", gdb_stdout);
1109 }
1110 }
1111
09722039
SG
1112 gdb_flush (gdb_stdout);
1113
1114 return TCL_OK;
1115}
754e5da2
SG
1116\f
1117static void
1118tk_command (cmd, from_tty)
1119 char *cmd;
1120 int from_tty;
1121{
546b8ca7
SG
1122 int retval;
1123 char *result;
1124 struct cleanup *old_chain;
1125
572977a5
FF
1126 /* Catch case of no argument, since this will make the tcl interpreter dump core. */
1127 if (cmd == NULL)
1128 error_no_arg ("tcl command to interpret");
1129
546b8ca7
SG
1130 retval = Tcl_Eval (interp, cmd);
1131
1132 result = strdup (interp->result);
754e5da2 1133
546b8ca7
SG
1134 old_chain = make_cleanup (free, result);
1135
1136 if (retval != TCL_OK)
1137 error (result);
1138
1139 printf_unfiltered ("%s\n", result);
1140
1141 do_cleanups (old_chain);
754e5da2
SG
1142}
1143
1144static void
1145cleanup_init (ignored)
1146 int ignored;
1147{
754e5da2
SG
1148 if (interp != NULL)
1149 Tcl_DeleteInterp (interp);
1150 interp = NULL;
1151}
1152
637b1661
SG
1153/* Come here during long calculations to check for GUI events. Usually invoked
1154 via the QUIT macro. */
1155
1156static void
1157gdbtk_interactive ()
1158{
1159 /* Tk_DoOneEvent (TK_DONT_WAIT|TK_IDLE_EVENTS); */
1160}
1161
479f0f18
SG
1162/* Come here when there is activity on the X file descriptor. */
1163
1164static void
1165x_event (signo)
1166 int signo;
1167{
1168 /* Process pending events */
1169
1170 while (Tk_DoOneEvent (TK_DONT_WAIT|TK_ALL_EVENTS) != 0);
1171}
1172
1173static int
1174gdbtk_wait (pid, ourstatus)
1175 int pid;
1176 struct target_waitstatus *ourstatus;
1177{
736a82e7
SG
1178 struct sigaction action;
1179 static sigset_t nullsigmask = {0};
1180
1181#ifndef SA_RESTART
1182 /* Needed for SunOS 4.1.x */
1183#define SA_RESTART 0
546b8ca7 1184#endif
479f0f18 1185
736a82e7
SG
1186 action.sa_handler = x_event;
1187 action.sa_mask = nullsigmask;
1188 action.sa_flags = SA_RESTART;
1189 sigaction(SIGIO, &action, NULL);
1190
479f0f18
SG
1191 pid = target_wait (pid, ourstatus);
1192
736a82e7
SG
1193 action.sa_handler = SIG_IGN;
1194 sigaction(SIGIO, &action, NULL);
479f0f18
SG
1195
1196 return pid;
1197}
1198
1199/* This is called from execute_command, and provides a wrapper around
1200 various command routines in a place where both protocol messages and
1201 user input both flow through. Mostly this is used for indicating whether
1202 the target process is running or not.
1203*/
1204
1205static void
1206gdbtk_call_command (cmdblk, arg, from_tty)
1207 struct cmd_list_element *cmdblk;
1208 char *arg;
1209 int from_tty;
1210{
fda6fadc 1211 running_now = 0;
479f0f18
SG
1212 if (cmdblk->class == class_run)
1213 {
fda6fadc 1214 running_now = 1;
4e327047 1215 Tcl_Eval (interp, "gdbtk_tcl_busy");
479f0f18 1216 (*cmdblk->function.cfunc)(arg, from_tty);
4e327047 1217 Tcl_Eval (interp, "gdbtk_tcl_idle");
fda6fadc 1218 running_now = 0;
479f0f18
SG
1219 }
1220 else
1221 (*cmdblk->function.cfunc)(arg, from_tty);
1222}
1223
5bac2b50
FF
1224/* This function is called instead of gdb's internal command loop. This is the
1225 last chance to do anything before entering the main Tk event loop. */
1226
1227static void
1228tk_command_loop ()
1229{
41756e56
FF
1230 extern GDB_FILE *instream;
1231
1232 /* We no longer want to use stdin as the command input stream */
1233 instream = NULL;
5bac2b50
FF
1234 Tcl_Eval (interp, "gdbtk_tcl_preloop");
1235 Tk_MainLoop ();
1236}
1237
754e5da2
SG
1238static void
1239gdbtk_init ()
1240{
1241 struct cleanup *old_chain;
1242 char *gdbtk_filename;
479f0f18 1243 int i;
736a82e7
SG
1244 struct sigaction action;
1245 static sigset_t nullsigmask = {0};
754e5da2 1246
fe58c81f
FF
1247 /* If there is no DISPLAY environment variable, Tk_Init below will fail,
1248 causing gdb to abort. If instead we simply return here, gdb will
1249 gracefully degrade to using the command line interface. */
1250
1251 if (getenv ("DISPLAY") == NULL)
1252 return;
1253
754e5da2
SG
1254 old_chain = make_cleanup (cleanup_init, 0);
1255
1256 /* First init tcl and tk. */
1257
1258 interp = Tcl_CreateInterp ();
1259
1260 if (!interp)
1261 error ("Tcl_CreateInterp failed");
1262
754e5da2
SG
1263 if (Tcl_Init(interp) != TCL_OK)
1264 error ("Tcl_Init failed: %s", interp->result);
1265
1266 if (Tk_Init(interp) != TCL_OK)
1267 error ("Tk_Init failed: %s", interp->result);
1268
86db943c
SG
1269 Tcl_CreateCommand (interp, "gdb_cmd", call_wrapper, gdb_cmd, NULL);
1270 Tcl_CreateCommand (interp, "gdb_loc", call_wrapper, gdb_loc, NULL);
1271 Tcl_CreateCommand (interp, "gdb_sourcelines", call_wrapper, gdb_sourcelines,
1272 NULL);
1273 Tcl_CreateCommand (interp, "gdb_listfiles", call_wrapper, gdb_listfiles,
746d1df4 1274 NULL);
86db943c
SG
1275 Tcl_CreateCommand (interp, "gdb_stop", call_wrapper, gdb_stop, NULL);
1276 Tcl_CreateCommand (interp, "gdb_regnames", call_wrapper, gdb_regnames, NULL);
1277 Tcl_CreateCommand (interp, "gdb_fetch_registers", call_wrapper,
1278 gdb_fetch_registers, NULL);
1279 Tcl_CreateCommand (interp, "gdb_changed_register_list", call_wrapper,
1280 gdb_changed_register_list, NULL);
09722039
SG
1281 Tcl_CreateCommand (interp, "gdb_disassemble", call_wrapper,
1282 gdb_disassemble, NULL);
1283 Tcl_CreateCommand (interp, "gdb_eval", call_wrapper, gdb_eval, NULL);
6131622e
SG
1284 Tcl_CreateCommand (interp, "gdb_get_breakpoint_list", call_wrapper,
1285 gdb_get_breakpoint_list, NULL);
1286 Tcl_CreateCommand (interp, "gdb_get_breakpoint_info", call_wrapper,
1287 gdb_get_breakpoint_info, NULL);
754e5da2 1288
5bac2b50 1289 command_loop_hook = tk_command_loop;
b607efe7
FF
1290 print_frame_info_listing_hook =
1291 (void (*) PARAMS ((struct symtab *, int, int, int))) null_routine;
09722039
SG
1292 query_hook = gdbtk_query;
1293 flush_hook = gdbtk_flush;
1294 create_breakpoint_hook = gdbtk_create_breakpoint;
1295 delete_breakpoint_hook = gdbtk_delete_breakpoint;
6131622e 1296 modify_breakpoint_hook = gdbtk_modify_breakpoint;
09722039
SG
1297 interactive_hook = gdbtk_interactive;
1298 target_wait_hook = gdbtk_wait;
1299 call_command_hook = gdbtk_call_command;
41756e56
FF
1300 readline_begin_hook = gdbtk_readline_begin;
1301 readline_hook = gdbtk_readline;
1302 readline_end_hook = gdbtk_readline_end;
754e5da2 1303
cd2df226 1304 /* Get the file descriptor for the X server */
479f0f18 1305
047465fd 1306 x_fd = ConnectionNumber (Tk_Display (Tk_MainWindow (interp)));
479f0f18
SG
1307
1308 /* Setup for I/O interrupts */
1309
736a82e7
SG
1310 action.sa_mask = nullsigmask;
1311 action.sa_flags = 0;
1312 action.sa_handler = SIG_IGN;
1313 sigaction(SIGIO, &action, NULL);
1314
1315#ifdef FIOASYNC
1316 i = 1;
1317 if (ioctl (x_fd, FIOASYNC, &i))
1318 perror_with_name ("gdbtk_init: ioctl FIOASYNC failed");
479f0f18 1319
77a89957 1320#ifdef SIOCSPGRP
736a82e7
SG
1321 i = getpid();
1322 if (ioctl (x_fd, SIOCSPGRP, &i))
1323 perror_with_name ("gdbtk_init: ioctl SIOCSPGRP failed");
45f90c50
MM
1324
1325#else
1326#ifdef F_SETOWN
1327 i = getpid();
1328 if (fcntl (x_fd, F_SETOWN, i))
1329 perror_with_name ("gdbtk_init: fcntl F_SETOWN failed");
1330#endif /* F_SETOWN */
1331#endif /* !SIOCSPGRP */
546b8ca7
SG
1332#else
1333 if (ioctl (x_fd, I_SETSIG, S_INPUT|S_RDNORM) < 0)
736a82e7
SG
1334 perror_with_name ("gdbtk_init: ioctl I_SETSIG failed");
1335#endif /* ifndef FIOASYNC */
479f0f18 1336
754e5da2
SG
1337 add_com ("tk", class_obscure, tk_command,
1338 "Send a command directly into tk.");
09722039 1339
09722039
SG
1340 Tcl_LinkVar (interp, "disassemble-from-exec", (char *)&disassemble_from_exec,
1341 TCL_LINK_INT);
1342
1343 /* Load up gdbtk.tcl after all the environment stuff has been setup. */
1344
1345 gdbtk_filename = getenv ("GDBTK_FILENAME");
1346 if (!gdbtk_filename)
1347 if (access ("gdbtk.tcl", R_OK) == 0)
1348 gdbtk_filename = "gdbtk.tcl";
1349 else
1350 gdbtk_filename = GDBTK_FILENAME;
1351
724498fd
SG
1352/* Defer setup of fputs_unfiltered_hook to near the end so that error messages
1353 prior to this point go to stdout/stderr. */
1354
1355 fputs_unfiltered_hook = gdbtk_fputs;
1356
09722039 1357 if (Tcl_EvalFile (interp, gdbtk_filename) != TCL_OK)
724498fd
SG
1358 {
1359 fputs_unfiltered_hook = NULL; /* Force errors to stdout/stderr */
1360
1361 fprintf_unfiltered (stderr, "%s:%d: %s\n", gdbtk_filename,
1362 interp->errorLine, interp->result);
b66051ec
SG
1363
1364 fputs_unfiltered ("Stack trace:\n", gdb_stderr);
1365 fputs_unfiltered (Tcl_GetVar (interp, "errorInfo", 0), gdb_stderr);
1366 error ("");
724498fd 1367 }
09722039
SG
1368
1369 discard_cleanups (old_chain);
754e5da2
SG
1370}
1371
3f37b696 1372/* Come here during initialize_all_files () */
754e5da2
SG
1373
1374void
1375_initialize_gdbtk ()
1376{
c5197511
SG
1377 if (use_windows)
1378 {
1379 /* Tell the rest of the world that Gdbtk is now set up. */
754e5da2 1380
c5197511
SG
1381 init_ui_hook = gdbtk_init;
1382 }
754e5da2 1383}
This page took 0.179557 seconds and 4 git commands to generate.