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