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