]> Git Repo - binutils.git/blob - gdb/gdbtk.c
* gdb/gdbserver/Makefile.in (docdir): Removed.
[binutils.git] / gdb / gdbtk.c
1 /* Tcl/Tk interface routines.
2    Copyright 1994, 1995, 1996 Free Software Foundation, Inc.
3
4    Written by Stu Grossman <[email protected]> of Cygnus Support.
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
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"
30 #include <tcl.h>
31 #include <tk.h>
32 #ifdef ANSI_PROTOTYPES
33 #include <stdarg.h>
34 #else
35 #include <varargs.h>
36 #endif
37 #include <signal.h>
38 #include <fcntl.h>
39 #include <unistd.h>
40 #include <setjmp.h>
41 #include "top.h"
42 #include <sys/ioctl.h>
43 #include "gdb_string.h"
44 #include "dis-asm.h"
45 #include <stdio.h>
46 #include "gdbcmd.h"
47
48 #ifndef FIOASYNC
49 #include <sys/stropts.h>
50 #endif
51
52 /* Some versions (1.3.79, 1.3.81) of Linux don't support SIOCSPGRP the way
53    gdbtk wants to use it... */
54 #ifdef __linux__
55 #undef SIOCSPGRP
56 #endif
57
58 /* Handle for TCL interpreter */
59
60 static Tcl_Interp *interp = NULL;
61
62 /* Handle for TK main window */
63
64 static Tk_Window mainWindow = NULL;
65
66 static int x_fd;                /* X network socket */
67
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.  */
74
75 static 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.  */
83
84 static int disassemble_from_exec = -1;
85
86 /* Supply malloc calls for tcl/tk.  */
87
88 char *
89 Tcl_Malloc (size)
90      unsigned int size;
91 {
92   return xmalloc (size);
93 }
94
95 char *
96 Tcl_Realloc (ptr, size)
97      char *ptr;
98      unsigned int size;
99 {
100   return xrealloc (ptr, size);
101 }
102
103 void
104 Tcl_Free(ptr)
105      char *ptr;
106 {
107   free (ptr);
108 }
109
110 static void
111 null_routine(arg)
112      int arg;
113 {
114 }
115
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.
122
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).  */
129
130 /* Dynamic string header for stdout. */
131
132 static Tcl_DString *result_ptr;
133 \f
134 static void
135 gdbtk_flush (stream)
136      FILE *stream;
137 {
138 #if 0
139   /* Force immediate screen update */
140
141   Tcl_VarEval (interp, "gdbtk_tcl_flush", NULL);
142 #endif
143 }
144
145 static void
146 gdbtk_fputs (ptr, stream)
147      const char *ptr;
148      FILE *stream;
149 {
150
151   if (result_ptr)
152     Tcl_DStringAppend (result_ptr, (char *)ptr, -1);
153   else
154     {
155       Tcl_DString str;
156
157       Tcl_DStringInit (&str);
158
159       Tcl_DStringAppend (&str, "gdbtk_tcl_fputs", -1);
160       Tcl_DStringAppendElement (&str, (char *)ptr);
161
162       Tcl_Eval (interp, Tcl_DStringValue (&str));
163       Tcl_DStringFree (&str);
164     }
165 }
166
167 static int
168 gdbtk_query (query, args)
169      char *query;
170      va_list args;
171 {
172   char buf[200], *merge[2];
173   char *command;
174   long val;
175
176   vsprintf (buf, query, args);
177   merge[0] = "gdbtk_tcl_query";
178   merge[1] = buf;
179   command = Tcl_Merge (2, merge);
180   Tcl_Eval (interp, command);
181   free (command);
182
183   val = atol (interp->result);
184   return val;
185 }
186
187 /* VARARGS */
188 static void
189 #ifdef ANSI_PROTOTYPES
190 gdbtk_readline_begin (char *format, ...)
191 #else
192 gdbtk_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
216 static char *
217 gdbtk_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
238 static void
239 gdbtk_readline_end ()
240 {
241   Tcl_Eval (interp, "gdbtk_tcl_readline_end");
242 }
243
244 \f
245 static void
246 #ifdef ANSI_PROTOTYPES
247 dsprintf_append_element (Tcl_DString *dsp, char *format, ...)
248 #else
249 dsprintf_append_element (va_alist)
250      va_dcl
251 #endif
252 {
253   va_list args;
254   char buf[1024];
255
256 #ifdef ANSI_PROTOTYPES
257   va_start (args, format);
258 #else
259   Tcl_DString *dsp;
260   char *format;
261
262   va_start (args);
263   dsp = va_arg (args, Tcl_DString *);
264   format = va_arg (args, char *);
265 #endif
266
267   vsprintf (buf, format, args);
268
269   Tcl_DStringAppendElement (dsp, buf);
270 }
271
272 static int
273 gdb_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
292 static int
293 gdb_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
321   if (!b || b->type != bp_breakpoint)
322     error ("Breakpoint #%d does not exist", bpnum);
323
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
348 static void
349 breakpoint_notify(b, action)
350      struct breakpoint *b;
351      const char *action;
352 {
353   char buf[100];
354   int v;
355
356   if (b->type != bp_breakpoint)
357     return;
358
359   /* We ensure that ACTION contains no special Tcl characters, so we
360      can do this.  */
361   sprintf (buf, "gdbtk_tcl_breakpoint %s %d", action, b->number);
362
363   v = Tcl_Eval (interp, buf);
364
365   if (v != TCL_OK)
366     {
367       gdbtk_fputs (interp->result, gdb_stdout);
368       gdbtk_fputs ("\n", gdb_stdout);
369     }
370 }
371
372 static void
373 gdbtk_create_breakpoint(b)
374      struct breakpoint *b;
375 {
376   breakpoint_notify (b, "create");
377 }
378
379 static void
380 gdbtk_delete_breakpoint(b)
381      struct breakpoint *b;
382 {
383   breakpoint_notify (b, "delete");
384 }
385
386 static void
387 gdbtk_modify_breakpoint(b)
388      struct breakpoint *b;
389 {
390   breakpoint_notify (b, "modify");
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
396 static int
397 gdb_loc (clientData, interp, argc, argv)
398      ClientData clientData;
399      Tcl_Interp *interp;
400      int argc;
401      char *argv[];
402 {
403   char *filename;
404   struct symtab_and_line sal;
405   char *funcname;
406   CORE_ADDR pc;
407
408   if (argc == 1)
409     {
410       pc = selected_frame ? selected_frame->pc : stop_pc;
411       sal = find_pc_line (pc, 0);
412     }
413   else if (argc == 2)
414     {
415       struct symtabs_and_lines sals;
416       int nelts;
417
418       sals = decode_line_spec (argv[1], 1);
419
420       nelts = sals.nelts;
421       sal = sals.sals[0];
422       free (sals.sals);
423
424       if (sals.nelts != 1)
425         error ("Ambiguous line spec");
426
427       pc = sal.pc;
428     }
429   else
430     error ("wrong # args");
431
432   if (sal.symtab)
433     Tcl_DStringAppendElement (result_ptr, sal.symtab->filename);
434   else
435     Tcl_DStringAppendElement (result_ptr, "");
436
437   find_pc_partial_function (pc, &funcname, NULL, NULL);
438   Tcl_DStringAppendElement (result_ptr, funcname);
439
440   filename = symtab_to_filename (sal.symtab);
441   Tcl_DStringAppendElement (result_ptr, filename);
442
443   dsprintf_append_element (result_ptr, "%d", sal.line); /* line number */
444
445   dsprintf_append_element (result_ptr, "0x%lx", pc); /* PC */
446
447   return TCL_OK;
448 }
449 \f
450 /* This implements the TCL command `gdb_eval'. */
451
452 static int
453 gdb_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)
464     error ("wrong # args");
465
466   expr = parse_expression (argv[1]);
467
468   old_chain = make_cleanup (free_current_contents, &expr);
469
470   val = evaluate_expression (expr);
471
472   val_print (VALUE_TYPE (val), VALUE_CONTENTS (val), VALUE_ADDRESS (val),
473              gdb_stdout, 0, 0, 0, 0);
474
475   do_cleanups (old_chain);
476
477   return TCL_OK;
478 }
479 \f
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
484 static int
485 gdb_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;
494
495   if (argc != 2)
496     error ("wrong # args");
497
498   symtab = lookup_symtab (argv[1]);
499
500   if (!symtab)
501     error ("No such file");
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     {
508       Tcl_DStringAppendElement (result_ptr, "");
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
523       dsprintf_append_element (result_ptr, "%d", le->line);
524     }
525
526   return TCL_OK;
527 }
528 \f
529 static int
530 map_arg_registers (argc, argv, func, argp)
531      int argc;
532      char *argv[];
533      void (*func) PARAMS ((int regnum, void *argp));
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
567         error ("bad register number");
568     }
569
570   return TCL_OK;
571 }
572
573 static void
574 get_register_name (regnum, argp)
575      int regnum;
576      void *argp;                /* Ignored */
577 {
578   Tcl_DStringAppendElement (result_ptr, reg_names[regnum]);
579 }
580
581 /* This implements the TCL command `gdb_regnames', which returns a list of
582    all of the register names. */
583
584 static int
585 gdb_regnames (clientData, interp, argc, argv)
586      ClientData clientData;
587      Tcl_Interp *interp;
588      int argc;
589      char *argv[];
590 {
591   argc--;
592   argv++;
593
594   return map_arg_registers (argc, argv, get_register_name, 0);
595 }
596
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
609 static void
610 get_register (regnum, fp)
611      int regnum;
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     {
620       Tcl_DStringAppendElement (result_ptr, "Optimized out");
621       return;
622     }
623
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
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);
648
649   Tcl_DStringAppend (result_ptr, " ", -1);
650 }
651
652 static int
653 gdb_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)
662     error ("wrong # args");
663
664   argc--;
665   argv++;
666
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
676 static char old_regs[REGISTER_BYTES];
677
678 static void
679 register_changed_p (regnum, argp)
680      int regnum;
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
693   /* Found a changed register.  Save new value and return its number. */
694
695   memcpy (&old_regs[REGISTER_BYTE (regnum)], raw_buffer,
696           REGISTER_RAW_SIZE (regnum));
697
698   dsprintf_append_element (result_ptr, "%d", regnum);
699 }
700
701 static int
702 gdb_changed_register_list (clientData, interp, argc, argv)
703      ClientData clientData;
704      Tcl_Interp *interp;
705      int argc;
706      char *argv[];
707 {
708   argc--;
709   argv++;
710
711   return map_arg_registers (argc, argv, register_changed_p, NULL);
712 }
713 \f
714 /* This implements the TCL command `gdb_cmd', which sends its argument into
715    the GDB command scanner.  */
716
717 static int
718 gdb_cmd (clientData, interp, argc, argv)
719      ClientData clientData;
720      Tcl_Interp *interp;
721      int argc;
722      char *argv[];
723 {
724   if (argc != 2)
725     error ("wrong # args");
726
727   if (running_now)
728     return TCL_OK;
729
730   execute_command (argv[1], 1);
731
732   bpstat_do_actions (&stop_bpstat);
733
734   return TCL_OK;
735 }
736
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
744 static int
745 call_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;
755   Tcl_DString result, *old_result_ptr;
756
757   Tcl_DStringInit (&result);
758   old_result_ptr = result_ptr;
759   result_ptr = &result;
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
772       gdb_flush (gdb_stderr);   /* Flush error output */
773
774       gdb_flush (gdb_stdout);   /* Sometimes error output comes here as well */
775
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.  */
779
780       Tcl_Eval (interp, "gdbtk_tcl_idle");
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
789   Tcl_DStringResult (interp, &result);
790   result_ptr = old_result_ptr;
791
792   return val;
793 }
794
795 static int
796 gdb_listfiles (clientData, interp, argc, argv)
797      ClientData clientData;
798      Tcl_Interp *interp;
799      int argc;
800      char *argv[];
801 {
802   struct objfile *objfile;
803   struct partial_symtab *psymtab;
804   struct symtab *symtab;
805
806   ALL_PSYMTABS (objfile, psymtab)
807     Tcl_DStringAppendElement (result_ptr, psymtab->filename);
808
809   ALL_SYMTABS (objfile, symtab)
810     Tcl_DStringAppendElement (result_ptr, symtab->filename);
811
812   return TCL_OK;
813 }
814
815 static int
816 gdb_stop (clientData, interp, argc, argv)
817      ClientData clientData;
818      Tcl_Interp *interp;
819      int argc;
820      char *argv[];
821 {
822   target_stop ();
823
824   return TCL_OK;
825 }
826 \f
827 /* This implements the TCL command `gdb_disassemble'.  */
828
829 static int
830 gdbtk_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
855 struct my_line_entry {
856   int line;
857   CORE_ADDR start_pc;
858   CORE_ADDR end_pc;
859 };
860
861 static int
862 compare_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
880 static int
881 gdb_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;
889   static disassemble_info di;
890   static int di_initialized;
891
892   if (! di_initialized)
893     {
894       INIT_DISASSEMBLE_INFO (di, gdb_stdout,
895                              (fprintf_ftype) fprintf_unfiltered);
896       di.memory_error_func = dis_asm_memory_error;
897       di.print_address_func = dis_asm_print_address;
898       di_initialized = 1;
899     }
900
901   if (argc != 3 && argc != 4)
902     error ("wrong # args");
903
904   if (strcmp (argv[1], "source") == 0)
905     mixed_source_and_assembly = 1;
906   else if (strcmp (argv[1], "nosource") == 0)
907     mixed_source_and_assembly = 0;
908   else
909     error ("First arg must be 'source' or 'nosource'");
910
911   low = parse_and_eval_address (argv[2]);
912
913   if (argc == 3)
914     {
915       if (find_pc_partial_function (low, NULL, &low, &high) == 0)
916         error ("No function contains specified address");
917     }
918   else
919     high = parse_and_eval_address (argv[3]);
920
921   /* If disassemble_from_exec == -1, then we use the following heuristic to
922      determine whether or not to do disassembly from target memory or from the
923      exec file:
924
925      If we're debugging a local process, read target memory, instead of the
926      exec file.  This makes disassembly of functions in shared libs work
927      correctly.
928
929      Else, we're debugging a remote process, and should disassemble from the
930      exec file for speed.  However, this is no good if the target modifies its
931      code (for relocation, or whatever).
932    */
933
934   if (disassemble_from_exec == -1)
935     if (strcmp (target_shortname, "child") == 0
936         || strcmp (target_shortname, "procfs") == 0
937         || strcmp (target_shortname, "vxprocess") == 0)
938       disassemble_from_exec = 0; /* It's a child process, read inferior mem */
939     else
940       disassemble_from_exec = 1; /* It's remote, read the exec file */
941
942   if (disassemble_from_exec)
943     di.read_memory_func = gdbtk_dis_asm_read_memory;
944   else
945     di.read_memory_func = dis_asm_read_memory;
946
947   /* If just doing straight assembly, all we need to do is disassemble
948      everything between low and high.  If doing mixed source/assembly, we've
949      got a totally different path to follow.  */
950
951   if (mixed_source_and_assembly)
952     {                           /* Come here for mixed source/assembly */
953       /* The idea here is to present a source-O-centric view of a function to
954          the user.  This means that things are presented in source order, with
955          (possibly) out of order assembly immediately following.  */
956       struct symtab *symtab;
957       struct linetable_entry *le;
958       int nlines;
959       int newlines;
960       struct my_line_entry *mle;
961       struct symtab_and_line sal;
962       int i;
963       int out_of_order;
964       int next_line;
965
966       symtab = find_pc_symtab (low); /* Assume symtab is valid for whole PC range */
967
968       if (!symtab)
969         goto assembly_only;
970
971 /* First, convert the linetable to a bunch of my_line_entry's.  */
972
973       le = symtab->linetable->item;
974       nlines = symtab->linetable->nitems;
975
976       if (nlines <= 0)
977         goto assembly_only;
978
979       mle = (struct my_line_entry *) alloca (nlines * sizeof (struct my_line_entry));
980
981       out_of_order = 0;
982
983 /* Copy linetable entries for this function into our data structure, creating
984    end_pc's and setting out_of_order as appropriate.  */
985
986 /* First, skip all the preceding functions.  */
987
988       for (i = 0; i < nlines - 1 && le[i].pc < low; i++) ;
989
990 /* Now, copy all entries before the end of this function.  */
991
992       newlines = 0;
993       for (; i < nlines - 1 && le[i].pc < high; i++)
994         {
995           if (le[i].line == le[i + 1].line
996               && le[i].pc == le[i + 1].pc)
997             continue;           /* Ignore duplicates */
998
999           mle[newlines].line = le[i].line;
1000           if (le[i].line > le[i + 1].line)
1001             out_of_order = 1;
1002           mle[newlines].start_pc = le[i].pc;
1003           mle[newlines].end_pc = le[i + 1].pc;
1004           newlines++;
1005         }
1006
1007 /* If we're on the last line, and it's part of the function, then we need to
1008    get the end pc in a special way.  */
1009
1010       if (i == nlines - 1
1011           && le[i].pc < high)
1012         {
1013           mle[newlines].line = le[i].line;
1014           mle[newlines].start_pc = le[i].pc;
1015           sal = find_pc_line (le[i].pc, 0);
1016           mle[newlines].end_pc = sal.end;
1017           newlines++;
1018         }
1019
1020 /* Now, sort mle by line #s (and, then by addresses within lines). */
1021
1022       if (out_of_order)
1023         qsort (mle, newlines, sizeof (struct my_line_entry), compare_lines);
1024
1025 /* Now, for each line entry, emit the specified lines (unless they have been
1026    emitted before), followed by the assembly code for that line.  */
1027
1028       next_line = 0;            /* Force out first line */
1029       for (i = 0; i < newlines; i++)
1030         {
1031 /* Print out everything from next_line to the current line.  */
1032
1033           if (mle[i].line >= next_line)
1034             {
1035               if (next_line != 0)
1036                 print_source_lines (symtab, next_line, mle[i].line + 1, 0);
1037               else
1038                 print_source_lines (symtab, mle[i].line, mle[i].line + 1, 0);
1039
1040               next_line = mle[i].line + 1;
1041             }
1042
1043           for (pc = mle[i].start_pc; pc < mle[i].end_pc; )
1044             {
1045               QUIT;
1046               fputs_unfiltered ("    ", gdb_stdout);
1047               print_address (pc, gdb_stdout);
1048               fputs_unfiltered (":\t    ", gdb_stdout);
1049               pc += (*tm_print_insn) (pc, &di);
1050               fputs_unfiltered ("\n", gdb_stdout);
1051             }
1052         }
1053     }
1054   else
1055     {
1056 assembly_only:
1057       for (pc = low; pc < high; )
1058         {
1059           QUIT;
1060           fputs_unfiltered ("    ", gdb_stdout);
1061           print_address (pc, gdb_stdout);
1062           fputs_unfiltered (":\t    ", gdb_stdout);
1063           pc += (*tm_print_insn) (pc, &di);
1064           fputs_unfiltered ("\n", gdb_stdout);
1065         }
1066     }
1067
1068   gdb_flush (gdb_stdout);
1069
1070   return TCL_OK;
1071 }
1072 \f
1073 static void
1074 tk_command (cmd, from_tty)
1075      char *cmd;
1076      int from_tty;
1077 {
1078   int retval;
1079   char *result;
1080   struct cleanup *old_chain;
1081
1082   /* Catch case of no argument, since this will make the tcl interpreter dump core. */
1083   if (cmd == NULL)
1084     error_no_arg ("tcl command to interpret");
1085
1086   retval = Tcl_Eval (interp, cmd);
1087
1088   result = strdup (interp->result);
1089
1090   old_chain = make_cleanup (free, result);
1091
1092   if (retval != TCL_OK)
1093     error (result);
1094
1095   printf_unfiltered ("%s\n", result);
1096
1097   do_cleanups (old_chain);
1098 }
1099
1100 static void
1101 cleanup_init (ignored)
1102      int ignored;
1103 {
1104   if (mainWindow != NULL)
1105     Tk_DestroyWindow (mainWindow);
1106   mainWindow = NULL;
1107
1108   if (interp != NULL)
1109     Tcl_DeleteInterp (interp);
1110   interp = NULL;
1111 }
1112
1113 /* Come here during long calculations to check for GUI events.  Usually invoked
1114    via the QUIT macro.  */
1115
1116 static void
1117 gdbtk_interactive ()
1118 {
1119   /* Tk_DoOneEvent (TK_DONT_WAIT|TK_IDLE_EVENTS); */
1120 }
1121
1122 /* Come here when there is activity on the X file descriptor. */
1123
1124 static void
1125 x_event (signo)
1126      int signo;
1127 {
1128   /* Process pending events */
1129
1130   while (Tk_DoOneEvent (TK_DONT_WAIT|TK_ALL_EVENTS) != 0);
1131 }
1132
1133 static int
1134 gdbtk_wait (pid, ourstatus)
1135      int pid;
1136      struct target_waitstatus *ourstatus;
1137 {
1138   struct sigaction action;
1139   static sigset_t nullsigmask = {0};
1140
1141 #ifndef SA_RESTART
1142   /* Needed for SunOS 4.1.x */
1143 #define SA_RESTART 0
1144 #endif
1145
1146   action.sa_handler = x_event;
1147   action.sa_mask = nullsigmask;
1148   action.sa_flags = SA_RESTART;
1149   sigaction(SIGIO, &action, NULL);
1150
1151   pid = target_wait (pid, ourstatus);
1152
1153   action.sa_handler = SIG_IGN;
1154   sigaction(SIGIO, &action, NULL);
1155
1156   return pid;
1157 }
1158
1159 /* This is called from execute_command, and provides a wrapper around
1160    various command routines in a place where both protocol messages and
1161    user input both flow through.  Mostly this is used for indicating whether
1162    the target process is running or not.
1163 */
1164
1165 static void
1166 gdbtk_call_command (cmdblk, arg, from_tty)
1167      struct cmd_list_element *cmdblk;
1168      char *arg;
1169      int from_tty;
1170 {
1171   running_now = 0;
1172   if (cmdblk->class == class_run)
1173     {
1174       running_now = 1;
1175       Tcl_Eval (interp, "gdbtk_tcl_busy");
1176       (*cmdblk->function.cfunc)(arg, from_tty);
1177       Tcl_Eval (interp, "gdbtk_tcl_idle");
1178       running_now = 0;
1179     }
1180   else
1181     (*cmdblk->function.cfunc)(arg, from_tty);
1182 }
1183
1184 /* This function is called instead of gdb's internal command loop.  This is the
1185    last chance to do anything before entering the main Tk event loop. */
1186
1187 static void
1188 tk_command_loop ()
1189 {
1190   extern GDB_FILE *instream;
1191
1192   /* We no longer want to use stdin as the command input stream */
1193   instream = NULL;
1194   Tcl_Eval (interp, "gdbtk_tcl_preloop");
1195   Tk_MainLoop ();
1196 }
1197
1198 static void
1199 gdbtk_init ()
1200 {
1201   struct cleanup *old_chain;
1202   char *gdbtk_filename;
1203   int i;
1204   struct sigaction action;
1205   static sigset_t nullsigmask = {0};
1206
1207   old_chain = make_cleanup (cleanup_init, 0);
1208
1209   /* First init tcl and tk. */
1210
1211   interp = Tcl_CreateInterp ();
1212
1213   if (!interp)
1214     error ("Tcl_CreateInterp failed");
1215
1216   mainWindow = Tk_CreateMainWindow (interp, NULL, "gdb", "Gdb");
1217
1218   if (!mainWindow)
1219     return;                     /* DISPLAY probably not set */
1220
1221   if (Tcl_Init(interp) != TCL_OK)
1222     error ("Tcl_Init failed: %s", interp->result);
1223
1224   if (Tk_Init(interp) != TCL_OK)
1225     error ("Tk_Init failed: %s", interp->result);
1226
1227   Tcl_CreateCommand (interp, "gdb_cmd", call_wrapper, gdb_cmd, NULL);
1228   Tcl_CreateCommand (interp, "gdb_loc", call_wrapper, gdb_loc, NULL);
1229   Tcl_CreateCommand (interp, "gdb_sourcelines", call_wrapper, gdb_sourcelines,
1230                      NULL);
1231   Tcl_CreateCommand (interp, "gdb_listfiles", call_wrapper, gdb_listfiles,
1232                      NULL);
1233   Tcl_CreateCommand (interp, "gdb_stop", call_wrapper, gdb_stop, NULL);
1234   Tcl_CreateCommand (interp, "gdb_regnames", call_wrapper, gdb_regnames, NULL);
1235   Tcl_CreateCommand (interp, "gdb_fetch_registers", call_wrapper,
1236                      gdb_fetch_registers, NULL);
1237   Tcl_CreateCommand (interp, "gdb_changed_register_list", call_wrapper,
1238                      gdb_changed_register_list, NULL);
1239   Tcl_CreateCommand (interp, "gdb_disassemble", call_wrapper,
1240                      gdb_disassemble, NULL);
1241   Tcl_CreateCommand (interp, "gdb_eval", call_wrapper, gdb_eval, NULL);
1242   Tcl_CreateCommand (interp, "gdb_get_breakpoint_list", call_wrapper,
1243                      gdb_get_breakpoint_list, NULL);
1244   Tcl_CreateCommand (interp, "gdb_get_breakpoint_info", call_wrapper,
1245                      gdb_get_breakpoint_info, NULL);
1246
1247   command_loop_hook = tk_command_loop;
1248   print_frame_info_listing_hook = null_routine;
1249   query_hook = gdbtk_query;
1250   flush_hook = gdbtk_flush;
1251   create_breakpoint_hook = gdbtk_create_breakpoint;
1252   delete_breakpoint_hook = gdbtk_delete_breakpoint;
1253   modify_breakpoint_hook = gdbtk_modify_breakpoint;
1254   interactive_hook = gdbtk_interactive;
1255   target_wait_hook = gdbtk_wait;
1256   call_command_hook = gdbtk_call_command;
1257   readline_begin_hook = gdbtk_readline_begin;
1258   readline_hook = gdbtk_readline;
1259   readline_end_hook = gdbtk_readline_end;
1260
1261   /* Get the file descriptor for the X server */
1262
1263   x_fd = ConnectionNumber (Tk_Display (mainWindow));
1264
1265   /* Setup for I/O interrupts */
1266
1267   action.sa_mask = nullsigmask;
1268   action.sa_flags = 0;
1269   action.sa_handler = SIG_IGN;
1270   sigaction(SIGIO, &action, NULL);
1271
1272 #ifdef FIOASYNC
1273   i = 1;
1274   if (ioctl (x_fd, FIOASYNC, &i))
1275     perror_with_name ("gdbtk_init: ioctl FIOASYNC failed");
1276
1277 #ifdef SIOCSPGRP
1278   i = getpid();
1279   if (ioctl (x_fd, SIOCSPGRP, &i))
1280     perror_with_name ("gdbtk_init: ioctl SIOCSPGRP failed");
1281
1282 #else
1283 #ifdef F_SETOWN
1284   i = getpid();
1285   if (fcntl (x_fd, F_SETOWN, i))
1286     perror_with_name ("gdbtk_init: fcntl F_SETOWN failed");
1287 #endif  /* F_SETOWN */
1288 #endif  /* !SIOCSPGRP */
1289 #else
1290   if (ioctl (x_fd,  I_SETSIG, S_INPUT|S_RDNORM) < 0)
1291     perror_with_name ("gdbtk_init: ioctl I_SETSIG failed");
1292 #endif /* ifndef FIOASYNC */
1293
1294   add_com ("tk", class_obscure, tk_command,
1295            "Send a command directly into tk.");
1296
1297   Tcl_LinkVar (interp, "disassemble-from-exec", (char *)&disassemble_from_exec,
1298                TCL_LINK_INT);
1299
1300   /* Load up gdbtk.tcl after all the environment stuff has been setup.  */
1301
1302   gdbtk_filename = getenv ("GDBTK_FILENAME");
1303   if (!gdbtk_filename)
1304     if (access ("gdbtk.tcl", R_OK) == 0)
1305       gdbtk_filename = "gdbtk.tcl";
1306     else
1307       gdbtk_filename = GDBTK_FILENAME;
1308
1309 /* Defer setup of fputs_unfiltered_hook to near the end so that error messages
1310    prior to this point go to stdout/stderr.  */
1311
1312   fputs_unfiltered_hook = gdbtk_fputs;
1313
1314   if (Tcl_EvalFile (interp, gdbtk_filename) != TCL_OK)
1315     {
1316       fputs_unfiltered_hook = NULL; /* Force errors to stdout/stderr */
1317
1318       fprintf_unfiltered (stderr, "%s:%d: %s\n", gdbtk_filename,
1319                           interp->errorLine, interp->result);
1320
1321       fputs_unfiltered ("Stack trace:\n", gdb_stderr);
1322       fputs_unfiltered (Tcl_GetVar (interp, "errorInfo", 0), gdb_stderr);
1323       error ("");
1324     }
1325
1326   discard_cleanups (old_chain);
1327 }
1328
1329 /* Come here during initialize_all_files () */
1330
1331 void
1332 _initialize_gdbtk ()
1333 {
1334   if (use_windows)
1335     {
1336       /* Tell the rest of the world that Gdbtk is now set up. */
1337
1338       init_ui_hook = gdbtk_init;
1339     }
1340 }
This page took 0.097069 seconds and 4 git commands to generate.