* tracepoint.c (set_raw_tracepoint): make sure there's a trailing slash on
[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"
018d76dd
KS
30#include "gdbcore.h"
31#include "tracepoint.h"
32
33#ifdef _WIN32
34#include <winuser.h>
35#endif
36
754e5da2
SG
37#include <tcl.h>
38#include <tk.h>
2476848a
MH
39#include <itcl.h>
40#include <tix.h>
41
018d76dd
KS
42#include "guitcl.h"
43
2476848a 44#ifdef IDE
018d76dd 45/* start-sanitize-ide */
2476848a
MH
46#include "event.h"
47#include "idetcl.h"
018d76dd
KS
48#include "ilutk.h"
49/* end-sanitize-ide */
2476848a
MH
50#endif
51
73d3dbd4 52#ifdef ANSI_PROTOTYPES
85c613aa
C
53#include <stdarg.h>
54#else
cd2df226 55#include <varargs.h>
85c613aa 56#endif
cd2df226
SG
57#include <signal.h>
58#include <fcntl.h>
8532893d 59#include <unistd.h>
86db943c
SG
60#include <setjmp.h>
61#include "top.h"
736a82e7 62#include <sys/ioctl.h>
2b576293 63#include "gdb_string.h"
09722039 64#include "dis-asm.h"
6131622e
SG
65#include <stdio.h>
66#include "gdbcmd.h"
736a82e7 67
8a19b35a 68#ifndef WINNT
736a82e7 69#ifndef FIOASYNC
546b8ca7
SG
70#include <sys/stropts.h>
71#endif
8a19b35a
MH
72#endif
73
018d76dd
KS
74#ifdef __CYGWIN32__
75#include <sys/time.h>
76#endif
77
8a19b35a
MH
78#ifdef WINNT
79#define GDBTK_PATH_SEP ";"
80#else
81#define GDBTK_PATH_SEP ":"
82#endif
754e5da2 83
8b3f9ed6 84/* Some versions (1.3.79, 1.3.81) of Linux don't support SIOCSPGRP the way
3f37b696 85 gdbtk wants to use it... */
8b3f9ed6
MM
86#ifdef __linux__
87#undef SIOCSPGRP
88#endif
89
018d76dd
KS
90int gdbtk_load_hash PARAMS ((char *, unsigned long));
91int (*ui_load_progress_hook) PARAMS ((char *, unsigned long));
92
b607efe7
FF
93static void null_routine PARAMS ((int));
94static void gdbtk_flush PARAMS ((FILE *));
95static void gdbtk_fputs PARAMS ((const char *, FILE *));
96static int gdbtk_query PARAMS ((const char *, va_list));
97static char *gdbtk_readline PARAMS ((char *));
2476848a 98static void gdbtk_init PARAMS ((char *));
b607efe7
FF
99static void tk_command_loop PARAMS ((void));
100static void gdbtk_call_command PARAMS ((struct cmd_list_element *, char *, int));
101static int gdbtk_wait PARAMS ((int, struct target_waitstatus *));
102static void x_event PARAMS ((int));
103static void gdbtk_interactive PARAMS ((void));
104static void cleanup_init PARAMS ((int));
105static void tk_command PARAMS ((char *, int));
106static int gdb_disassemble PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
107static int compare_lines PARAMS ((const PTR, const PTR));
108static int gdbtk_dis_asm_read_memory PARAMS ((bfd_vma, bfd_byte *, int, disassemble_info *));
8a19b35a 109static int gdb_path_conv PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
b607efe7 110static int gdb_stop PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
018d76dd
KS
111static int gdb_confirm_quit PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
112static int gdb_force_quit PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
b607efe7 113static int gdb_listfiles PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
99c98415 114static int gdb_listfuncs PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
b607efe7
FF
115static int call_wrapper PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
116static int gdb_cmd PARAMS ((ClientData, Tcl_Interp *, int, char *argv[]));
117static int gdb_fetch_registers PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
118static void gdbtk_readline_end PARAMS ((void));
119static int gdb_changed_register_list PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
120static void register_changed_p PARAMS ((int, void *));
121static int gdb_get_breakpoint_list PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
122static int gdb_get_breakpoint_info PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
123static void breakpoint_notify PARAMS ((struct breakpoint *, const char *));
124static void gdbtk_create_breakpoint PARAMS ((struct breakpoint *));
125static void gdbtk_delete_breakpoint PARAMS ((struct breakpoint *));
126static void gdbtk_modify_breakpoint PARAMS ((struct breakpoint *));
127static int gdb_loc PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
128static int gdb_eval PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
129static int gdb_sourcelines PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
130static int map_arg_registers PARAMS ((int, char *[], void (*) (int, void *), void *));
131static void get_register_name PARAMS ((int, void *));
132static int gdb_regnames PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
133static void get_register PARAMS ((int, void *));
018d76dd
KS
134static int gdb_target_has_execution_command PARAMS ((ClientData, Tcl_Interp *, int, char *argv[]));
135static int gdb_load_info PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]));
136static int gdb_get_vars_command PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]));
137static int gdb_get_function_command PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]));
138static int gdb_get_line_command PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]));
139static int gdb_get_file_command PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]));
140static int gdb_tracepoint_exists_command PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]));
141static int gdb_get_tracepoint_info PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]));
142static int gdb_actions_command PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]));
143static int gdb_prompt_command PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]));
144static void gdbtk_create_tracepoint PARAMS ((struct tracepoint *));
145static void gdbtk_delete_tracepoint PARAMS ((struct tracepoint *));
146static void tracepoint_notify PARAMS ((struct tracepoint *, const char *));
b607efe7 147
754e5da2 148/* Handle for TCL interpreter */
fda6fadc 149
754e5da2
SG
150static Tcl_Interp *interp = NULL;
151
018d76dd 152#ifndef WINNT
479f0f18 153static int x_fd; /* X network socket */
018d76dd 154#endif
479f0f18 155
fda6fadc
SS
156/* This variable is true when the inferior is running. Although it's
157 possible to disable most input from widgets and thus prevent
158 attempts to do anything while the inferior is running, any commands
159 that get through - even a simple memory read - are Very Bad, and
160 may cause GDB to crash or behave strangely. So, this variable
161 provides an extra layer of defense. */
09722039 162
fda6fadc
SS
163static int running_now;
164
165/* This variable determines where memory used for disassembly is read from.
166 If > 0, then disassembly comes from the exec file rather than the
167 target (which might be at the other end of a slow serial link). If
168 == 0 then disassembly comes from target. If < 0 disassembly is
169 automatically switched to the target if it's an inferior process,
170 otherwise the exec file is used. */
09722039
SG
171
172static int disassemble_from_exec = -1;
173
9b119644
ILT
174#ifndef _WIN32
175
176/* Supply malloc calls for tcl/tk. We do not want to do this on
177 Windows, because Tcl_Alloc is probably in a DLL which will not call
178 the mmalloc routines. */
8c19daa1
SG
179
180char *
a5a6e3bd 181Tcl_Alloc (size)
8c19daa1
SG
182 unsigned int size;
183{
184 return xmalloc (size);
185}
186
187char *
188Tcl_Realloc (ptr, size)
189 char *ptr;
190 unsigned int size;
191{
192 return xrealloc (ptr, size);
193}
194
195void
196Tcl_Free(ptr)
197 char *ptr;
198{
199 free (ptr);
200}
201
018d76dd 202#endif /* ! _WIN32 */
9b119644 203
754e5da2
SG
204static void
205null_routine(arg)
206 int arg;
207{
208}
209
018d76dd
KS
210#ifdef _WIN32
211
212/* On Windows, if we hold a file open, other programs can't write to
213 it. In particular, we don't want to hold the executable open,
214 because it will mean that people have to get out of the debugging
215 session in order to remake their program. So we close it, although
216 this will cost us if and when we need to reopen it. */
217
218static void
219close_bfds ()
220{
221 struct objfile *o;
222
223 ALL_OBJFILES (o)
224 {
225 if (o->obfd != NULL)
226 bfd_cache_close (o->obfd);
227 }
228
229 if (exec_bfd != NULL)
230 bfd_cache_close (exec_bfd);
231}
232
233#endif /* _WIN32 */
234
546b8ca7
SG
235/* The following routines deal with stdout/stderr data, which is created by
236 {f}printf_{un}filtered and friends. gdbtk_fputs and gdbtk_flush are the
237 lowest level of these routines and capture all output from the rest of GDB.
238 Normally they present their data to tcl via callbacks to the following tcl
239 routines: gdbtk_tcl_fputs, gdbtk_tcl_fputs_error, and gdbtk_flush. These
240 in turn call tk routines to update the display.
86db943c 241
546b8ca7
SG
242 Under some circumstances, you may want to collect the output so that it can
243 be returned as the value of a tcl procedure. This can be done by
244 surrounding the output routines with calls to start_saving_output and
245 finish_saving_output. The saved data can then be retrieved with
246 get_saved_output (but this must be done before the call to
247 finish_saving_output). */
86db943c 248
018d76dd 249/* Dynamic string for output. */
86db943c 250
6131622e 251static Tcl_DString *result_ptr;
018d76dd
KS
252
253/* Dynamic string for stderr. This is only used if result_ptr is
254 NULL. */
255
256static Tcl_DString *error_string_ptr;
754e5da2 257\f
754e5da2
SG
258static void
259gdbtk_flush (stream)
260 FILE *stream;
261{
6131622e 262#if 0
86db943c
SG
263 /* Force immediate screen update */
264
754e5da2 265 Tcl_VarEval (interp, "gdbtk_tcl_flush", NULL);
6131622e 266#endif
754e5da2
SG
267}
268
8532893d 269static void
86db943c 270gdbtk_fputs (ptr, stream)
8532893d 271 const char *ptr;
86db943c 272 FILE *stream;
8532893d 273{
6131622e 274 if (result_ptr)
018d76dd
KS
275 Tcl_DStringAppend (result_ptr, (char *) ptr, -1);
276 else if (error_string_ptr != NULL && stream == gdb_stderr)
277 Tcl_DStringAppend (error_string_ptr, (char *) ptr, -1);
6131622e 278 else
86db943c 279 {
6131622e 280 Tcl_DString str;
86db943c 281
6131622e 282 Tcl_DStringInit (&str);
8532893d 283
6131622e 284 Tcl_DStringAppend (&str, "gdbtk_tcl_fputs", -1);
45f90c50 285 Tcl_DStringAppendElement (&str, (char *)ptr);
8532893d 286
2476848a 287 Tcl_Eval (interp, Tcl_DStringValue (&str));
6131622e
SG
288 Tcl_DStringFree (&str);
289 }
8532893d
SG
290}
291
754e5da2 292static int
85c613aa 293gdbtk_query (query, args)
b607efe7 294 const char *query;
754e5da2
SG
295 va_list args;
296{
4e327047
TT
297 char buf[200], *merge[2];
298 char *command;
754e5da2
SG
299 long val;
300
6131622e 301 vsprintf (buf, query, args);
4e327047
TT
302 merge[0] = "gdbtk_tcl_query";
303 merge[1] = buf;
304 command = Tcl_Merge (2, merge);
305 Tcl_Eval (interp, command);
018d76dd 306 Tcl_Free (command);
754e5da2
SG
307
308 val = atol (interp->result);
309 return val;
310}
41756e56
FF
311
312/* VARARGS */
313static void
314#ifdef ANSI_PROTOTYPES
315gdbtk_readline_begin (char *format, ...)
316#else
317gdbtk_readline_begin (va_alist)
318 va_dcl
319#endif
320{
321 va_list args;
322 char buf[200], *merge[2];
323 char *command;
324
325#ifdef ANSI_PROTOTYPES
326 va_start (args, format);
327#else
328 char *format;
329 va_start (args);
330 format = va_arg (args, char *);
331#endif
332
333 vsprintf (buf, format, args);
334 merge[0] = "gdbtk_tcl_readline_begin";
335 merge[1] = buf;
336 command = Tcl_Merge (2, merge);
337 Tcl_Eval (interp, command);
338 free (command);
339}
340
341static char *
342gdbtk_readline (prompt)
343 char *prompt;
344{
345 char *merge[2];
346 char *command;
bd45f82f 347 int result;
41756e56 348
018d76dd
KS
349#ifdef _WIN32
350 close_bfds ();
351#endif
352
41756e56
FF
353 merge[0] = "gdbtk_tcl_readline";
354 merge[1] = prompt;
355 command = Tcl_Merge (2, merge);
bd45f82f
TT
356 result = Tcl_Eval (interp, command);
357 free (command);
358 if (result == TCL_OK)
41756e56
FF
359 {
360 return (strdup (interp -> result));
361 }
362 else
363 {
364 gdbtk_fputs (interp -> result, gdb_stdout);
365 gdbtk_fputs ("\n", gdb_stdout);
366 return (NULL);
367 }
368}
369
370static void
371gdbtk_readline_end ()
372{
373 Tcl_Eval (interp, "gdbtk_tcl_readline_end");
374}
375
754e5da2 376\f
6131622e 377static void
73d3dbd4 378#ifdef ANSI_PROTOTYPES
85c613aa
C
379dsprintf_append_element (Tcl_DString *dsp, char *format, ...)
380#else
6131622e
SG
381dsprintf_append_element (va_alist)
382 va_dcl
85c613aa 383#endif
6131622e
SG
384{
385 va_list args;
85c613aa
C
386 char buf[1024];
387
73d3dbd4 388#ifdef ANSI_PROTOTYPES
85c613aa
C
389 va_start (args, format);
390#else
6131622e
SG
391 Tcl_DString *dsp;
392 char *format;
6131622e
SG
393
394 va_start (args);
6131622e
SG
395 dsp = va_arg (args, Tcl_DString *);
396 format = va_arg (args, char *);
85c613aa 397#endif
6131622e
SG
398
399 vsprintf (buf, format, args);
400
401 Tcl_DStringAppendElement (dsp, buf);
402}
403
8a19b35a
MH
404static int
405gdb_path_conv (clientData, interp, argc, argv)
406 ClientData clientData;
407 Tcl_Interp *interp;
408 int argc;
409 char *argv[];
410{
411#ifdef WINNT
412 char pathname[256], *ptr;
413 if (argc != 2)
414 error ("wrong # args");
415 cygwin32_conv_to_full_win32_path (argv[1], pathname);
416 for (ptr = pathname; *ptr; ptr++)
417 {
418 if (*ptr == '\\')
419 *ptr = '/';
420 }
421#else
422 char *pathname = argv[1];
423#endif
424 Tcl_DStringAppend (result_ptr, pathname, strlen(pathname));
425 return TCL_OK;
426}
427
6131622e
SG
428static int
429gdb_get_breakpoint_list (clientData, interp, argc, argv)
430 ClientData clientData;
431 Tcl_Interp *interp;
432 int argc;
433 char *argv[];
434{
435 struct breakpoint *b;
436 extern struct breakpoint *breakpoint_chain;
437
438 if (argc != 1)
439 error ("wrong # args");
440
441 for (b = breakpoint_chain; b; b = b->next)
442 if (b->type == bp_breakpoint)
443 dsprintf_append_element (result_ptr, "%d", b->number);
444
445 return TCL_OK;
446}
447
448static int
449gdb_get_breakpoint_info (clientData, interp, argc, argv)
450 ClientData clientData;
451 Tcl_Interp *interp;
452 int argc;
453 char *argv[];
454{
455 struct symtab_and_line sal;
456 static char *bptypes[] = {"breakpoint", "hardware breakpoint", "until",
457 "finish", "watchpoint", "hardware watchpoint",
458 "read watchpoint", "access watchpoint",
459 "longjmp", "longjmp resume", "step resume",
460 "through sigtramp", "watchpoint scope",
461 "call dummy" };
27f1958c 462 static char *bpdisp[] = {"delete", "delstop", "disable", "donttouch"};
6131622e
SG
463 struct command_line *cmd;
464 int bpnum;
465 struct breakpoint *b;
466 extern struct breakpoint *breakpoint_chain;
018d76dd 467 char *funcname;
6131622e
SG
468
469 if (argc != 2)
470 error ("wrong # args");
471
472 bpnum = atoi (argv[1]);
473
474 for (b = breakpoint_chain; b; b = b->next)
475 if (b->number == bpnum)
476 break;
477
9468f8aa 478 if (!b || b->type != bp_breakpoint)
6131622e
SG
479 error ("Breakpoint #%d does not exist", bpnum);
480
6131622e
SG
481 sal = find_pc_line (b->address, 0);
482
483 Tcl_DStringAppendElement (result_ptr, symtab_to_filename (sal.symtab));
018d76dd
KS
484 find_pc_partial_function (b->address, &funcname, NULL, NULL);
485 Tcl_DStringAppendElement (result_ptr, funcname);
6131622e
SG
486 dsprintf_append_element (result_ptr, "%d", sal.line);
487 dsprintf_append_element (result_ptr, "0x%lx", b->address);
488 Tcl_DStringAppendElement (result_ptr, bptypes[b->type]);
489 Tcl_DStringAppendElement (result_ptr, b->enable == enabled ? "1" : "0");
490 Tcl_DStringAppendElement (result_ptr, bpdisp[b->disposition]);
6131622e
SG
491 dsprintf_append_element (result_ptr, "%d", b->ignore_count);
492
493 Tcl_DStringStartSublist (result_ptr);
494 for (cmd = b->commands; cmd; cmd = cmd->next)
495 Tcl_DStringAppendElement (result_ptr, cmd->line);
496 Tcl_DStringEndSublist (result_ptr);
497
498 Tcl_DStringAppendElement (result_ptr, b->cond_string);
499
500 dsprintf_append_element (result_ptr, "%d", b->thread);
501 dsprintf_append_element (result_ptr, "%d", b->hit_count);
502
503 return TCL_OK;
504}
505
754e5da2
SG
506static void
507breakpoint_notify(b, action)
508 struct breakpoint *b;
509 const char *action;
510{
32707df8 511 char buf[256];
754e5da2 512 int v;
2476848a 513 struct symtab_and_line sal;
754e5da2
SG
514
515 if (b->type != bp_breakpoint)
516 return;
517
4e327047
TT
518 /* We ensure that ACTION contains no special Tcl characters, so we
519 can do this. */
2476848a
MH
520 sal = find_pc_line (b->address, 0);
521 sprintf (buf, "gdbtk_tcl_breakpoint %s %d 0x%lx %d {%s}", action, b->number,
522 (long)b->address, sal.line, symtab_to_filename (sal.symtab));
754e5da2 523
6131622e 524 v = Tcl_Eval (interp, buf);
754e5da2
SG
525
526 if (v != TCL_OK)
527 {
546b8ca7
SG
528 gdbtk_fputs (interp->result, gdb_stdout);
529 gdbtk_fputs ("\n", gdb_stdout);
754e5da2 530 }
754e5da2
SG
531}
532
533static void
534gdbtk_create_breakpoint(b)
535 struct breakpoint *b;
536{
6131622e 537 breakpoint_notify (b, "create");
754e5da2
SG
538}
539
540static void
541gdbtk_delete_breakpoint(b)
542 struct breakpoint *b;
543{
6131622e 544 breakpoint_notify (b, "delete");
754e5da2
SG
545}
546
547static void
6131622e 548gdbtk_modify_breakpoint(b)
754e5da2
SG
549 struct breakpoint *b;
550{
6131622e 551 breakpoint_notify (b, "modify");
754e5da2
SG
552}
553\f
554/* This implements the TCL command `gdb_loc', which returns a list consisting
555 of the source and line number associated with the current pc. */
556
557static int
558gdb_loc (clientData, interp, argc, argv)
559 ClientData clientData;
560 Tcl_Interp *interp;
561 int argc;
562 char *argv[];
563{
564 char *filename;
754e5da2
SG
565 struct symtab_and_line sal;
566 char *funcname;
8532893d 567 CORE_ADDR pc;
754e5da2 568
018d76dd
KS
569 if (!have_full_symbols () && !have_partial_symbols ())
570 {
571 Tcl_SetResult (interp, "No symbol table is loaded", TCL_STATIC);
572 return TCL_ERROR;
573 }
574
754e5da2
SG
575 if (argc == 1)
576 {
1dfc8dfb 577 pc = selected_frame ? selected_frame->pc : stop_pc;
754e5da2
SG
578 sal = find_pc_line (pc, 0);
579 }
580 else if (argc == 2)
581 {
754e5da2 582 struct symtabs_and_lines sals;
8532893d 583 int nelts;
754e5da2
SG
584
585 sals = decode_line_spec (argv[1], 1);
586
8532893d
SG
587 nelts = sals.nelts;
588 sal = sals.sals[0];
589 free (sals.sals);
590
754e5da2 591 if (sals.nelts != 1)
6131622e 592 error ("Ambiguous line spec");
754e5da2 593
8532893d 594 pc = sal.pc;
754e5da2
SG
595 }
596 else
6131622e 597 error ("wrong # args");
754e5da2 598
754e5da2 599 if (sal.symtab)
6131622e 600 Tcl_DStringAppendElement (result_ptr, sal.symtab->filename);
754e5da2 601 else
6131622e 602 Tcl_DStringAppendElement (result_ptr, "");
8532893d
SG
603
604 find_pc_partial_function (pc, &funcname, NULL, NULL);
6131622e 605 Tcl_DStringAppendElement (result_ptr, funcname);
8532893d 606
637b1661 607 filename = symtab_to_filename (sal.symtab);
6131622e 608 Tcl_DStringAppendElement (result_ptr, filename);
8532893d 609
9468f8aa 610 dsprintf_append_element (result_ptr, "%d", sal.line); /* line number */
754e5da2 611
2476848a
MH
612 dsprintf_append_element (result_ptr, "0x%s", paddr_nz(pc)); /* PC in current frame */
613
614 dsprintf_append_element (result_ptr, "0x%s", paddr_nz(stop_pc)); /* Real PC */
8532893d 615
754e5da2
SG
616 return TCL_OK;
617}
618\f
09722039
SG
619/* This implements the TCL command `gdb_eval'. */
620
621static int
622gdb_eval (clientData, interp, argc, argv)
623 ClientData clientData;
624 Tcl_Interp *interp;
625 int argc;
626 char *argv[];
627{
628 struct expression *expr;
629 struct cleanup *old_chain;
630 value_ptr val;
631
632 if (argc != 2)
6131622e 633 error ("wrong # args");
09722039
SG
634
635 expr = parse_expression (argv[1]);
636
637 old_chain = make_cleanup (free_current_contents, &expr);
638
639 val = evaluate_expression (expr);
640
09722039
SG
641 val_print (VALUE_TYPE (val), VALUE_CONTENTS (val), VALUE_ADDRESS (val),
642 gdb_stdout, 0, 0, 0, 0);
09722039
SG
643
644 do_cleanups (old_chain);
645
646 return TCL_OK;
647}
018d76dd
KS
648
649/* gdb_get_mem addr form size num aschar*/
650/* dump a block of memory */
651/* addr: address of data to dump */
652/* form: a char indicating format */
653/* size: size of each element; 1,2,4, or 8 bytes*/
654/* num: the number of 'size' elements to return */
655/* acshar: an optional ascii character to use in ASCII dump */
656/* returns a list of 'num' elements followed by an optional */
657/* ASCII dump */
658static int
659gdb_get_mem (clientData, interp, argc, argv)
660 ClientData clientData;
661 Tcl_Interp *interp;
662 int argc;
663 char *argv[];
664{
665 int size, asize, num, i, j;
666 CORE_ADDR addr, saved_addr, ptr;
667 int format;
668 struct type *val_type;
669 value_ptr vptr;
670 char c, buff[128], aschar;
671
672 if (argc != 6)
673 error ("wrong # args");
674
675 addr = (CORE_ADDR)strtoul(argv[1],(char **)NULL,0);
676 saved_addr = addr;
677 format = *argv[2];
678 size = (int)strtoul(argv[3],(char **)NULL,0);
679 num = (int)strtoul(argv[4],(char **)NULL,0);
680 aschar = *argv[5];
681
682 switch (size) {
683 case 1:
684 val_type = builtin_type_char;
685 asize = 'b';
686 break;
687 case 2:
688 val_type = builtin_type_short;
689 asize = 'h';
690 break;
691 case 4:
692 val_type = builtin_type_int;
693 asize = 'w';
694 break;
695 case 8:
696 val_type = builtin_type_long_long;
697 asize = 'g';
698 break;
699 default:
700 val_type = builtin_type_char;
701 asize = 'b';
702 }
703
704 for (i=0; i < num; i++)
705 {
706 vptr = value_at (val_type, addr, (asection *)NULL);
707 print_scalar_formatted (VALUE_CONTENTS(vptr), val_type, format, asize, gdb_stdout);
708 fputs_unfiltered (" ", gdb_stdout);
709 addr += size;
710 }
711
712 if (aschar)
713 {
714 val_type = builtin_type_char;
715 ptr = saved_addr;
716 buff[0] = '"';
717 i = 1;
718 for (j=0; j < num*size; j++)
719 {
720 c = *(char *)VALUE_CONTENTS(value_at (val_type, ptr, (asection *)NULL));
721 if (c < 32 || c > 126)
722 c = aschar;
723 if (c == '"')
724 buff[i++] = '\\';
725 buff[i++] = c;
726 ptr++;
727 }
728 buff[i++] = '"';
729 buff[i] = 0;
730 fputs_unfiltered (buff, gdb_stdout);
731 }
732
733 return TCL_OK;
734}
735
736
5b21fb68
SG
737/* This implements the TCL command `gdb_sourcelines', which returns a list of
738 all of the lines containing executable code for the specified source file
739 (ie: lines where you can put breakpoints). */
740
741static int
742gdb_sourcelines (clientData, interp, argc, argv)
743 ClientData clientData;
744 Tcl_Interp *interp;
745 int argc;
746 char *argv[];
747{
748 struct symtab *symtab;
749 struct linetable_entry *le;
750 int nlines;
5b21fb68
SG
751
752 if (argc != 2)
6131622e 753 error ("wrong # args");
5b21fb68
SG
754
755 symtab = lookup_symtab (argv[1]);
756
757 if (!symtab)
6131622e 758 error ("No such file");
5b21fb68
SG
759
760 /* If there's no linetable, or no entries, then we are done. */
761
762 if (!symtab->linetable
763 || symtab->linetable->nitems == 0)
764 {
6131622e 765 Tcl_DStringAppendElement (result_ptr, "");
5b21fb68
SG
766 return TCL_OK;
767 }
768
769 le = symtab->linetable->item;
770 nlines = symtab->linetable->nitems;
771
772 for (;nlines > 0; nlines--, le++)
773 {
774 /* If the pc of this line is the same as the pc of the next line, then
775 just skip it. */
776 if (nlines > 1
777 && le->pc == (le + 1)->pc)
778 continue;
779
9468f8aa 780 dsprintf_append_element (result_ptr, "%d", le->line);
5b21fb68
SG
781 }
782
783 return TCL_OK;
784}
785\f
746d1df4
SG
786static int
787map_arg_registers (argc, argv, func, argp)
788 int argc;
789 char *argv[];
6131622e 790 void (*func) PARAMS ((int regnum, void *argp));
746d1df4
SG
791 void *argp;
792{
793 int regnum;
794
795 /* Note that the test for a valid register must include checking the
796 reg_names array because NUM_REGS may be allocated for the union of the
797 register sets within a family of related processors. In this case, the
798 trailing entries of reg_names will change depending upon the particular
799 processor being debugged. */
800
801 if (argc == 0) /* No args, just do all the regs */
802 {
803 for (regnum = 0;
804 regnum < NUM_REGS
805 && reg_names[regnum] != NULL
806 && *reg_names[regnum] != '\000';
807 regnum++)
808 func (regnum, argp);
809
810 return TCL_OK;
811 }
812
813 /* Else, list of register #s, just do listed regs */
814 for (; argc > 0; argc--, argv++)
815 {
816 regnum = atoi (*argv);
817
818 if (regnum >= 0
819 && regnum < NUM_REGS
820 && reg_names[regnum] != NULL
821 && *reg_names[regnum] != '\000')
822 func (regnum, argp);
823 else
6131622e 824 error ("bad register number");
746d1df4
SG
825 }
826
827 return TCL_OK;
828}
829
6131622e 830static void
746d1df4
SG
831get_register_name (regnum, argp)
832 int regnum;
833 void *argp; /* Ignored */
834{
6131622e 835 Tcl_DStringAppendElement (result_ptr, reg_names[regnum]);
746d1df4
SG
836}
837
5b21fb68
SG
838/* This implements the TCL command `gdb_regnames', which returns a list of
839 all of the register names. */
840
841static int
842gdb_regnames (clientData, interp, argc, argv)
843 ClientData clientData;
844 Tcl_Interp *interp;
845 int argc;
846 char *argv[];
847{
746d1df4
SG
848 argc--;
849 argv++;
850
b607efe7 851 return map_arg_registers (argc, argv, get_register_name, NULL);
746d1df4
SG
852}
853
746d1df4
SG
854#ifndef REGISTER_CONVERTIBLE
855#define REGISTER_CONVERTIBLE(x) (0 != 0)
856#endif
857
858#ifndef REGISTER_CONVERT_TO_VIRTUAL
859#define REGISTER_CONVERT_TO_VIRTUAL(x, y, z, a)
860#endif
861
862#ifndef INVALID_FLOAT
863#define INVALID_FLOAT(x, y) (0 != 0)
864#endif
865
6131622e 866static void
746d1df4 867get_register (regnum, fp)
6131622e 868 int regnum;
746d1df4
SG
869 void *fp;
870{
871 char raw_buffer[MAX_REGISTER_RAW_SIZE];
872 char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
873 int format = (int)fp;
874
875 if (read_relative_register_raw_bytes (regnum, raw_buffer))
876 {
6131622e 877 Tcl_DStringAppendElement (result_ptr, "Optimized out");
746d1df4
SG
878 return;
879 }
880
746d1df4
SG
881 /* Convert raw data to virtual format if necessary. */
882
883 if (REGISTER_CONVERTIBLE (regnum))
884 {
885 REGISTER_CONVERT_TO_VIRTUAL (regnum, REGISTER_VIRTUAL_TYPE (regnum),
886 raw_buffer, virtual_buffer);
887 }
888 else
889 memcpy (virtual_buffer, raw_buffer, REGISTER_VIRTUAL_SIZE (regnum));
890
3d9f68c0
FF
891 if (format == 'r')
892 {
893 int j;
894 printf_filtered ("0x");
895 for (j = 0; j < REGISTER_RAW_SIZE (regnum); j++)
896 {
897 register int idx = TARGET_BYTE_ORDER == BIG_ENDIAN ? j
898 : REGISTER_RAW_SIZE (regnum) - 1 - j;
899 printf_filtered ("%02x", (unsigned char)raw_buffer[idx]);
900 }
901 }
902 else
903 val_print (REGISTER_VIRTUAL_TYPE (regnum), virtual_buffer, 0,
904 gdb_stdout, format, 1, 0, Val_pretty_default);
746d1df4 905
6131622e 906 Tcl_DStringAppend (result_ptr, " ", -1);
746d1df4
SG
907}
908
909static int
910gdb_fetch_registers (clientData, interp, argc, argv)
911 ClientData clientData;
912 Tcl_Interp *interp;
913 int argc;
914 char *argv[];
915{
916 int format;
917
918 if (argc < 2)
6131622e 919 error ("wrong # args");
5b21fb68 920
746d1df4
SG
921 argc--;
922 argv++;
5b21fb68 923
746d1df4
SG
924 argc--;
925 format = **argv++;
926
b607efe7 927 return map_arg_registers (argc, argv, get_register, (void *) format);
746d1df4
SG
928}
929
930/* This contains the previous values of the registers, since the last call to
931 gdb_changed_register_list. */
932
933static char old_regs[REGISTER_BYTES];
934
6131622e 935static void
746d1df4 936register_changed_p (regnum, argp)
6131622e 937 int regnum;
746d1df4
SG
938 void *argp; /* Ignored */
939{
940 char raw_buffer[MAX_REGISTER_RAW_SIZE];
746d1df4
SG
941
942 if (read_relative_register_raw_bytes (regnum, raw_buffer))
943 return;
944
945 if (memcmp (&old_regs[REGISTER_BYTE (regnum)], raw_buffer,
946 REGISTER_RAW_SIZE (regnum)) == 0)
947 return;
948
fda6fadc 949 /* Found a changed register. Save new value and return its number. */
746d1df4
SG
950
951 memcpy (&old_regs[REGISTER_BYTE (regnum)], raw_buffer,
952 REGISTER_RAW_SIZE (regnum));
953
9468f8aa 954 dsprintf_append_element (result_ptr, "%d", regnum);
746d1df4
SG
955}
956
957static int
958gdb_changed_register_list (clientData, interp, argc, argv)
959 ClientData clientData;
960 Tcl_Interp *interp;
961 int argc;
962 char *argv[];
963{
746d1df4
SG
964 argc--;
965 argv++;
966
967 return map_arg_registers (argc, argv, register_changed_p, NULL);
5b21fb68
SG
968}
969\f
fda6fadc 970/* This implements the TCL command `gdb_cmd', which sends its argument into
754e5da2
SG
971 the GDB command scanner. */
972
973static int
974gdb_cmd (clientData, interp, argc, argv)
975 ClientData clientData;
976 Tcl_Interp *interp;
977 int argc;
978 char *argv[];
979{
018d76dd
KS
980 Tcl_DString *save_ptr = NULL;
981
754e5da2 982 if (argc != 2)
6131622e 983 error ("wrong # args");
754e5da2 984
fda6fadc
SS
985 if (running_now)
986 return TCL_OK;
987
018d76dd
KS
988 /* for the load instruction (and possibly others later) we
989 set result_ptr to NULL so gdbtk_fputs() will not buffer
990 all the data until the command is finished. */
991
992 if (strncmp("load ",argv[1],5) == 0) {
993 Tcl_DStringAppend (result_ptr, "", -1);
994 save_ptr = result_ptr;
995 result_ptr = NULL;
996 }
997
86db943c 998 execute_command (argv[1], 1);
479f0f18 999
754e5da2 1000 bpstat_do_actions (&stop_bpstat);
018d76dd
KS
1001
1002 if (save_ptr)
1003 result_ptr = save_ptr;
754e5da2 1004
754e5da2
SG
1005 return TCL_OK;
1006}
1007
c14cabba
AC
1008/* Client of call_wrapper - this routine performs the actual call to
1009 the client function. */
1010
1011struct wrapped_call_args
1012{
1013 Tcl_Interp *interp;
1014 Tcl_CmdProc *func;
1015 int argc;
1016 char **argv;
1017 int val;
1018};
1019
1020static int
1021wrapped_call (args)
1022 struct wrapped_call_args *args;
1023{
1024 args->val = (*args->func) (args->func, args->interp, args->argc, args->argv);
1025 return 1;
1026}
1027
86db943c
SG
1028/* This routine acts as a top-level for all GDB code called by tcl/Tk. It
1029 handles cleanups, and calls to return_to_top_level (usually via error).
1030 This is necessary in order to prevent a longjmp out of the bowels of Tk,
1031 possibly leaving things in a bad state. Since this routine can be called
1032 recursively, it needs to save and restore the contents of the jmp_buf as
1033 necessary. */
1034
1035static int
1036call_wrapper (clientData, interp, argc, argv)
1037 ClientData clientData;
1038 Tcl_Interp *interp;
1039 int argc;
1040 char *argv[];
1041{
c14cabba 1042 struct wrapped_call_args wrapped_args;
6131622e 1043 Tcl_DString result, *old_result_ptr;
018d76dd 1044 Tcl_DString error_string, *old_error_string_ptr;
6131622e
SG
1045
1046 Tcl_DStringInit (&result);
1047 old_result_ptr = result_ptr;
1048 result_ptr = &result;
86db943c 1049
018d76dd
KS
1050 Tcl_DStringInit (&error_string);
1051 old_error_string_ptr = error_string_ptr;
1052 error_string_ptr = &error_string;
1053
c14cabba
AC
1054 wrapped_args.func = (Tcl_CmdProc *)clientData;
1055 wrapped_args.interp = interp;
1056 wrapped_args.argc = argc;
1057 wrapped_args.argv = argv;
1058 wrapped_args.val = 0;
86db943c 1059
c14cabba 1060 if (!catch_errors (wrapped_call, &wrapped_args, "", RETURN_MASK_ALL))
86db943c 1061 {
c14cabba 1062 wrapped_args.val = TCL_ERROR; /* Flag an error for TCL */
86db943c 1063
86db943c
SG
1064 gdb_flush (gdb_stderr); /* Flush error output */
1065
09722039
SG
1066 gdb_flush (gdb_stdout); /* Sometimes error output comes here as well */
1067
fda6fadc
SS
1068 /* In case of an error, we may need to force the GUI into idle
1069 mode because gdbtk_call_command may have bombed out while in
1070 the command routine. */
86db943c 1071
40dffa42 1072 running_now = 0;
4e327047 1073 Tcl_Eval (interp, "gdbtk_tcl_idle");
86db943c
SG
1074 }
1075
018d76dd
KS
1076 if (Tcl_DStringLength (&error_string) == 0)
1077 {
1078 Tcl_DStringResult (interp, &result);
1079 Tcl_DStringFree (&error_string);
1080 }
1081 else if (Tcl_DStringLength (&result) == 0)
1082 {
1083 Tcl_DStringResult (interp, &error_string);
1084 Tcl_DStringFree (&result);
1085 }
1086 else
1087 {
1088 Tcl_ResetResult (interp);
1089 Tcl_AppendResult (interp, Tcl_DStringValue (&result),
1090 Tcl_DStringValue (&error_string), (char *) NULL);
1091 Tcl_DStringFree (&result);
1092 Tcl_DStringFree (&error_string);
1093 }
1094
6131622e 1095 result_ptr = old_result_ptr;
018d76dd
KS
1096 error_string_ptr = old_error_string_ptr;
1097
1098#ifdef _WIN32
1099 close_bfds ();
1100#endif
6131622e 1101
c14cabba 1102 return wrapped_args.val;
86db943c
SG
1103}
1104
754e5da2
SG
1105static int
1106gdb_listfiles (clientData, interp, argc, argv)
1107 ClientData clientData;
1108 Tcl_Interp *interp;
1109 int argc;
1110 char *argv[];
1111{
754e5da2
SG
1112 struct objfile *objfile;
1113 struct partial_symtab *psymtab;
546b8ca7 1114 struct symtab *symtab;
754e5da2
SG
1115
1116 ALL_PSYMTABS (objfile, psymtab)
6131622e 1117 Tcl_DStringAppendElement (result_ptr, psymtab->filename);
754e5da2 1118
546b8ca7 1119 ALL_SYMTABS (objfile, symtab)
6131622e 1120 Tcl_DStringAppendElement (result_ptr, symtab->filename);
546b8ca7 1121
754e5da2
SG
1122 return TCL_OK;
1123}
479f0f18 1124
99c98415
MH
1125static int
1126gdb_listfuncs (clientData, interp, argc, argv)
1127 ClientData clientData;
1128 Tcl_Interp *interp;
1129 int argc;
1130 char *argv[];
1131{
1132 struct symtab *symtab;
1133 struct blockvector *bv;
1134 struct block *b;
1135 struct symbol *sym;
1136 int i,j;
1137
1138 if (argc != 2)
1139 error ("wrong # args");
1140
1141 symtab = lookup_symtab (argv[1]);
1142
1143 if (!symtab)
1144 error ("No such file");
1145
1146 bv = BLOCKVECTOR (symtab);
1147 for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
1148 {
1149 b = BLOCKVECTOR_BLOCK (bv, i);
1150 /* Skip the sort if this block is always sorted. */
1151 if (!BLOCK_SHOULD_SORT (b))
1152 sort_block_syms (b);
1153 for (j = 0; j < BLOCK_NSYMS (b); j++)
1154 {
1155 sym = BLOCK_SYM (b, j);
1156 if (SYMBOL_CLASS (sym) == LOC_BLOCK)
1157 {
1158 Tcl_DStringAppendElement (result_ptr, SYMBOL_NAME(sym));
1159 }
1160 }
1161 }
1162 return TCL_OK;
1163}
1164
479f0f18
SG
1165static int
1166gdb_stop (clientData, interp, argc, argv)
1167 ClientData clientData;
1168 Tcl_Interp *interp;
1169 int argc;
1170 char *argv[];
1171{
c14cabba
AC
1172 if (target_stop)
1173 target_stop ();
1174 else
1175 quit_flag = 1; /* hope something sees this */
546b8ca7
SG
1176
1177 return TCL_OK;
479f0f18 1178}
018d76dd
KS
1179
1180/* Prepare to accept a new executable file. This is called when we
1181 want to clear away everything we know about the old file, without
1182 asking the user. The Tcl code will have already asked the user if
1183 necessary. After this is called, we should be able to run the
1184 `file' command without getting any questions. */
1185
1186static int
1187gdb_clear_file (clientData, interp, argc, argv)
1188 ClientData clientData;
1189 Tcl_Interp *interp;
1190 int argc;
1191 char *argv[];
1192{
1193 if (inferior_pid != 0 && target_has_execution)
1194 {
1195 if (attach_flag)
1196 target_detach (NULL, 0);
1197 else
1198 target_kill ();
1199 }
1200
1201 if (target_has_execution)
1202 pop_target ();
1203
1204 symbol_file_command (NULL, 0);
1205
1206 return TCL_OK;
1207}
1208
1209/* Ask the user to confirm an exit request. */
1210
1211static int
1212gdb_confirm_quit (clientData, interp, argc, argv)
1213 ClientData clientData;
1214 Tcl_Interp *interp;
1215 int argc;
1216 char *argv[];
1217{
1218 int ret;
1219
1220 ret = quit_confirm ();
1221 Tcl_DStringAppendElement (result_ptr, ret ? "1" : "0");
1222 return TCL_OK;
1223}
1224
1225/* Quit without asking for confirmation. */
1226
1227static int
1228gdb_force_quit (clientData, interp, argc, argv)
1229 ClientData clientData;
1230 Tcl_Interp *interp;
1231 int argc;
1232 char *argv[];
1233{
1234 quit_force ((char *) NULL, 1);
1235 return TCL_OK;
1236}
09722039
SG
1237\f
1238/* This implements the TCL command `gdb_disassemble'. */
479f0f18 1239
09722039
SG
1240static int
1241gdbtk_dis_asm_read_memory (memaddr, myaddr, len, info)
1242 bfd_vma memaddr;
1243 bfd_byte *myaddr;
1244 int len;
1245 disassemble_info *info;
1246{
1247 extern struct target_ops exec_ops;
1248 int res;
1249
1250 errno = 0;
1251 res = xfer_memory (memaddr, myaddr, len, 0, &exec_ops);
1252
1253 if (res == len)
1254 return 0;
1255 else
1256 if (errno == 0)
1257 return EIO;
1258 else
1259 return errno;
1260}
1261
1262/* We need a different sort of line table from the normal one cuz we can't
1263 depend upon implicit line-end pc's for lines. This is because of the
1264 reordering we are about to do. */
1265
1266struct my_line_entry {
1267 int line;
1268 CORE_ADDR start_pc;
1269 CORE_ADDR end_pc;
1270};
1271
1272static int
1273compare_lines (mle1p, mle2p)
1274 const PTR mle1p;
1275 const PTR mle2p;
1276{
1277 struct my_line_entry *mle1, *mle2;
1278 int val;
1279
1280 mle1 = (struct my_line_entry *) mle1p;
1281 mle2 = (struct my_line_entry *) mle2p;
1282
1283 val = mle1->line - mle2->line;
1284
1285 if (val != 0)
1286 return val;
1287
1288 return mle1->start_pc - mle2->start_pc;
1289}
1290
1291static int
1292gdb_disassemble (clientData, interp, argc, argv)
1293 ClientData clientData;
1294 Tcl_Interp *interp;
1295 int argc;
1296 char *argv[];
1297{
1298 CORE_ADDR pc, low, high;
1299 int mixed_source_and_assembly;
fc941258
DE
1300 static disassemble_info di;
1301 static int di_initialized;
1302
1303 if (! di_initialized)
1304 {
91550191
SG
1305 INIT_DISASSEMBLE_INFO_NO_ARCH (di, gdb_stdout,
1306 (fprintf_ftype) fprintf_unfiltered);
caeec767 1307 di.flavour = bfd_target_unknown_flavour;
fc941258
DE
1308 di.memory_error_func = dis_asm_memory_error;
1309 di.print_address_func = dis_asm_print_address;
1310 di_initialized = 1;
1311 }
09722039 1312
91550191
SG
1313 di.mach = tm_print_insn_info.mach;
1314 if (TARGET_BYTE_ORDER == BIG_ENDIAN)
e4bb9027 1315 di.endian = BFD_ENDIAN_BIG;
91550191 1316 else
e4bb9027 1317 di.endian = BFD_ENDIAN_LITTLE;
91550191 1318
09722039 1319 if (argc != 3 && argc != 4)
6131622e 1320 error ("wrong # args");
09722039
SG
1321
1322 if (strcmp (argv[1], "source") == 0)
1323 mixed_source_and_assembly = 1;
1324 else if (strcmp (argv[1], "nosource") == 0)
1325 mixed_source_and_assembly = 0;
1326 else
6131622e 1327 error ("First arg must be 'source' or 'nosource'");
09722039
SG
1328
1329 low = parse_and_eval_address (argv[2]);
1330
1331 if (argc == 3)
1332 {
1333 if (find_pc_partial_function (low, NULL, &low, &high) == 0)
6131622e 1334 error ("No function contains specified address");
09722039
SG
1335 }
1336 else
1337 high = parse_and_eval_address (argv[3]);
1338
1339 /* If disassemble_from_exec == -1, then we use the following heuristic to
1340 determine whether or not to do disassembly from target memory or from the
1341 exec file:
1342
1343 If we're debugging a local process, read target memory, instead of the
1344 exec file. This makes disassembly of functions in shared libs work
1345 correctly.
1346
1347 Else, we're debugging a remote process, and should disassemble from the
fda6fadc 1348 exec file for speed. However, this is no good if the target modifies its
09722039
SG
1349 code (for relocation, or whatever).
1350 */
1351
1352 if (disassemble_from_exec == -1)
1353 if (strcmp (target_shortname, "child") == 0
d7c4766c
SS
1354 || strcmp (target_shortname, "procfs") == 0
1355 || strcmp (target_shortname, "vxprocess") == 0)
09722039
SG
1356 disassemble_from_exec = 0; /* It's a child process, read inferior mem */
1357 else
1358 disassemble_from_exec = 1; /* It's remote, read the exec file */
1359
1360 if (disassemble_from_exec)
a76ef70a
SG
1361 di.read_memory_func = gdbtk_dis_asm_read_memory;
1362 else
1363 di.read_memory_func = dis_asm_read_memory;
09722039
SG
1364
1365 /* If just doing straight assembly, all we need to do is disassemble
1366 everything between low and high. If doing mixed source/assembly, we've
1367 got a totally different path to follow. */
1368
1369 if (mixed_source_and_assembly)
1370 { /* Come here for mixed source/assembly */
1371 /* The idea here is to present a source-O-centric view of a function to
1372 the user. This means that things are presented in source order, with
1373 (possibly) out of order assembly immediately following. */
1374 struct symtab *symtab;
1375 struct linetable_entry *le;
1376 int nlines;
c81a3fa9 1377 int newlines;
09722039
SG
1378 struct my_line_entry *mle;
1379 struct symtab_and_line sal;
1380 int i;
1381 int out_of_order;
c81a3fa9 1382 int next_line;
09722039
SG
1383
1384 symtab = find_pc_symtab (low); /* Assume symtab is valid for whole PC range */
1385
1386 if (!symtab)
1387 goto assembly_only;
1388
1389/* First, convert the linetable to a bunch of my_line_entry's. */
1390
1391 le = symtab->linetable->item;
1392 nlines = symtab->linetable->nitems;
1393
1394 if (nlines <= 0)
1395 goto assembly_only;
1396
1397 mle = (struct my_line_entry *) alloca (nlines * sizeof (struct my_line_entry));
1398
1399 out_of_order = 0;
1400
c81a3fa9
SG
1401/* Copy linetable entries for this function into our data structure, creating
1402 end_pc's and setting out_of_order as appropriate. */
1403
1404/* First, skip all the preceding functions. */
1405
1406 for (i = 0; i < nlines - 1 && le[i].pc < low; i++) ;
1407
1408/* Now, copy all entries before the end of this function. */
1409
1410 newlines = 0;
1411 for (; i < nlines - 1 && le[i].pc < high; i++)
09722039 1412 {
c81a3fa9
SG
1413 if (le[i].line == le[i + 1].line
1414 && le[i].pc == le[i + 1].pc)
1415 continue; /* Ignore duplicates */
1416
1417 mle[newlines].line = le[i].line;
09722039
SG
1418 if (le[i].line > le[i + 1].line)
1419 out_of_order = 1;
c81a3fa9
SG
1420 mle[newlines].start_pc = le[i].pc;
1421 mle[newlines].end_pc = le[i + 1].pc;
1422 newlines++;
09722039
SG
1423 }
1424
c81a3fa9
SG
1425/* If we're on the last line, and it's part of the function, then we need to
1426 get the end pc in a special way. */
1427
1428 if (i == nlines - 1
1429 && le[i].pc < high)
1430 {
1431 mle[newlines].line = le[i].line;
1432 mle[newlines].start_pc = le[i].pc;
1433 sal = find_pc_line (le[i].pc, 0);
1434 mle[newlines].end_pc = sal.end;
1435 newlines++;
1436 }
09722039
SG
1437
1438/* Now, sort mle by line #s (and, then by addresses within lines). */
1439
1440 if (out_of_order)
c81a3fa9 1441 qsort (mle, newlines, sizeof (struct my_line_entry), compare_lines);
09722039
SG
1442
1443/* Now, for each line entry, emit the specified lines (unless they have been
1444 emitted before), followed by the assembly code for that line. */
1445
c81a3fa9
SG
1446 next_line = 0; /* Force out first line */
1447 for (i = 0; i < newlines; i++)
09722039 1448 {
c81a3fa9
SG
1449/* Print out everything from next_line to the current line. */
1450
1451 if (mle[i].line >= next_line)
09722039 1452 {
c81a3fa9
SG
1453 if (next_line != 0)
1454 print_source_lines (symtab, next_line, mle[i].line + 1, 0);
09722039 1455 else
c81a3fa9
SG
1456 print_source_lines (symtab, mle[i].line, mle[i].line + 1, 0);
1457
1458 next_line = mle[i].line + 1;
09722039 1459 }
c81a3fa9 1460
09722039
SG
1461 for (pc = mle[i].start_pc; pc < mle[i].end_pc; )
1462 {
1463 QUIT;
1464 fputs_unfiltered (" ", gdb_stdout);
1465 print_address (pc, gdb_stdout);
1466 fputs_unfiltered (":\t ", gdb_stdout);
d039851f 1467 pc += (*tm_print_insn) (pc, &di);
09722039
SG
1468 fputs_unfiltered ("\n", gdb_stdout);
1469 }
1470 }
1471 }
1472 else
1473 {
1474assembly_only:
1475 for (pc = low; pc < high; )
1476 {
1477 QUIT;
1478 fputs_unfiltered (" ", gdb_stdout);
1479 print_address (pc, gdb_stdout);
1480 fputs_unfiltered (":\t ", gdb_stdout);
d039851f 1481 pc += (*tm_print_insn) (pc, &di);
09722039
SG
1482 fputs_unfiltered ("\n", gdb_stdout);
1483 }
1484 }
1485
09722039
SG
1486 gdb_flush (gdb_stdout);
1487
1488 return TCL_OK;
1489}
754e5da2
SG
1490\f
1491static void
1492tk_command (cmd, from_tty)
1493 char *cmd;
1494 int from_tty;
1495{
546b8ca7
SG
1496 int retval;
1497 char *result;
1498 struct cleanup *old_chain;
1499
572977a5
FF
1500 /* Catch case of no argument, since this will make the tcl interpreter dump core. */
1501 if (cmd == NULL)
1502 error_no_arg ("tcl command to interpret");
1503
546b8ca7
SG
1504 retval = Tcl_Eval (interp, cmd);
1505
1506 result = strdup (interp->result);
754e5da2 1507
546b8ca7
SG
1508 old_chain = make_cleanup (free, result);
1509
1510 if (retval != TCL_OK)
1511 error (result);
1512
1513 printf_unfiltered ("%s\n", result);
1514
1515 do_cleanups (old_chain);
754e5da2
SG
1516}
1517
1518static void
1519cleanup_init (ignored)
1520 int ignored;
1521{
754e5da2
SG
1522 if (interp != NULL)
1523 Tcl_DeleteInterp (interp);
1524 interp = NULL;
1525}
1526
637b1661
SG
1527/* Come here during long calculations to check for GUI events. Usually invoked
1528 via the QUIT macro. */
1529
1530static void
1531gdbtk_interactive ()
1532{
1533 /* Tk_DoOneEvent (TK_DONT_WAIT|TK_IDLE_EVENTS); */
1534}
1535
479f0f18
SG
1536/* Come here when there is activity on the X file descriptor. */
1537
1538static void
1539x_event (signo)
1540 int signo;
1541{
1542 /* Process pending events */
1543
f02156cf 1544 while (Tcl_DoOneEvent (TCL_DONT_WAIT|TCL_ALL_EVENTS) != 0);
479f0f18
SG
1545}
1546
018d76dd
KS
1547#ifdef __CYGWIN32__
1548
1549/* For Cygwin32, we use a timer to periodically check for Windows
1550 messages. FIXME: It would be better to not poll, but to instead
1551 rewrite the target_wait routines to serve as input sources.
1552 Unfortunately, that will be a lot of work. */
1553
1554static void
1555gdbtk_start_timer ()
1556{
1557 sigset_t nullsigmask;
1558 struct sigaction action;
1559 struct itimerval it;
1560
1561 sigemptyset (&nullsigmask);
1562
1563 action.sa_handler = x_event;
1564 action.sa_mask = nullsigmask;
1565 action.sa_flags = 0;
1566 sigaction (SIGALRM, &action, NULL);
1567
1568 it.it_interval.tv_sec = 0;
1569 /* Check for messages twice a second. */
1570 it.it_interval.tv_usec = 500 * 1000;
1571 it.it_value.tv_sec = 0;
1572 it.it_value.tv_usec = 500 * 1000;
1573
1574 setitimer (ITIMER_REAL, &it, NULL);
1575}
1576
1577static void
1578gdbtk_stop_timer ()
1579{
1580 sigset_t nullsigmask;
1581 struct sigaction action;
1582 struct itimerval it;
1583
1584 sigemptyset (&nullsigmask);
1585
1586 action.sa_handler = SIG_IGN;
1587 action.sa_mask = nullsigmask;
1588 action.sa_flags = 0;
1589 sigaction (SIGALRM, &action, NULL);
1590
1591 it.it_interval.tv_sec = 0;
1592 it.it_interval.tv_usec = 0;
1593 it.it_value.tv_sec = 0;
1594 it.it_value.tv_usec = 0;
1595 setitimer (ITIMER_REAL, &it, NULL);
1596}
1597
1598#endif
1599
1600/* This hook function is called whenever we want to wait for the
1601 target. */
1602
479f0f18
SG
1603static int
1604gdbtk_wait (pid, ourstatus)
1605 int pid;
1606 struct target_waitstatus *ourstatus;
1607{
018d76dd 1608#ifndef WINNT
736a82e7
SG
1609 struct sigaction action;
1610 static sigset_t nullsigmask = {0};
1611
018d76dd 1612
736a82e7
SG
1613#ifndef SA_RESTART
1614 /* Needed for SunOS 4.1.x */
1615#define SA_RESTART 0
546b8ca7 1616#endif
479f0f18 1617
736a82e7
SG
1618 action.sa_handler = x_event;
1619 action.sa_mask = nullsigmask;
1620 action.sa_flags = SA_RESTART;
1621 sigaction(SIGIO, &action, NULL);
018d76dd
KS
1622#endif /* WINNT */
1623
1624#ifdef __CYGWIN32__
1625 gdbtk_start_timer ();
8a19b35a 1626#endif
736a82e7 1627
479f0f18
SG
1628 pid = target_wait (pid, ourstatus);
1629
018d76dd
KS
1630#ifdef __CYGWIN32__
1631 gdbtk_stop_timer ();
1632#endif
1633
8a19b35a 1634#ifndef WINNT
018d76dd 1635 action.sa_handler = SIG_IGN;
8a19b35a
MH
1636 sigaction(SIGIO, &action, NULL);
1637#endif
479f0f18
SG
1638
1639 return pid;
1640}
1641
1642/* This is called from execute_command, and provides a wrapper around
1643 various command routines in a place where both protocol messages and
1644 user input both flow through. Mostly this is used for indicating whether
1645 the target process is running or not.
1646*/
1647
1648static void
1649gdbtk_call_command (cmdblk, arg, from_tty)
1650 struct cmd_list_element *cmdblk;
1651 char *arg;
1652 int from_tty;
1653{
fda6fadc 1654 running_now = 0;
018d76dd 1655 if (cmdblk->class == class_run || cmdblk->class == class_trace)
479f0f18 1656 {
fda6fadc 1657 running_now = 1;
4e327047 1658 Tcl_Eval (interp, "gdbtk_tcl_busy");
479f0f18 1659 (*cmdblk->function.cfunc)(arg, from_tty);
fda6fadc 1660 running_now = 0;
2476848a 1661 Tcl_Eval (interp, "gdbtk_tcl_idle");
479f0f18
SG
1662 }
1663 else
1664 (*cmdblk->function.cfunc)(arg, from_tty);
1665}
1666
5bac2b50
FF
1667/* This function is called instead of gdb's internal command loop. This is the
1668 last chance to do anything before entering the main Tk event loop. */
1669
1670static void
1671tk_command_loop ()
1672{
41756e56
FF
1673 extern GDB_FILE *instream;
1674
1675 /* We no longer want to use stdin as the command input stream */
1676 instream = NULL;
018d76dd
KS
1677
1678 if (Tcl_Eval (interp, "gdbtk_tcl_preloop") != TCL_OK)
1679 {
1680 char *msg;
1681
1682 /* Force errorInfo to be set up propertly. */
1683 Tcl_AddErrorInfo (interp, "");
1684
1685 msg = Tcl_GetVar (interp, "errorInfo", TCL_GLOBAL_ONLY);
1686#ifdef _WIN32
1687 MessageBox (NULL, msg, NULL, MB_OK | MB_ICONERROR | MB_TASKMODAL);
1688#else
1689 fputs_unfiltered (msg, gdb_stderr);
1690#endif
1691 }
1692
1693#ifdef _WIN32
1694 close_bfds ();
1695#endif
1696
5bac2b50
FF
1697 Tk_MainLoop ();
1698}
1699
9a2f9219
ILT
1700/* gdbtk_init installs this function as a final cleanup. */
1701
1702static void
1703gdbtk_cleanup (dummy)
1704 PTR dummy;
1705{
1706 Tcl_Finalize ();
1707}
1708
1709/* Initialize gdbtk. */
1710
754e5da2 1711static void
2476848a
MH
1712gdbtk_init ( argv0 )
1713 char *argv0;
754e5da2
SG
1714{
1715 struct cleanup *old_chain;
74089546 1716 char *lib, *gdbtk_lib, *gdbtk_lib_tmp, *gdbtk_file;
8a19b35a 1717 int i, found_main;
018d76dd 1718#ifndef WINNT
736a82e7
SG
1719 struct sigaction action;
1720 static sigset_t nullsigmask = {0};
018d76dd 1721#endif
2476848a 1722#ifdef IDE
018d76dd 1723 /* start-sanitize-ide */
2476848a
MH
1724 struct ide_event_handle *h;
1725 const char *errmsg;
1726 char *libexecdir;
018d76dd 1727 /* end-sanitize-ide */
2476848a 1728#endif
754e5da2 1729
fe58c81f
FF
1730 /* If there is no DISPLAY environment variable, Tk_Init below will fail,
1731 causing gdb to abort. If instead we simply return here, gdb will
1732 gracefully degrade to using the command line interface. */
1733
8a19b35a 1734#ifndef WINNT
fe58c81f
FF
1735 if (getenv ("DISPLAY") == NULL)
1736 return;
8a19b35a 1737#endif
fe58c81f 1738
754e5da2
SG
1739 old_chain = make_cleanup (cleanup_init, 0);
1740
1741 /* First init tcl and tk. */
2476848a 1742 Tcl_FindExecutable (argv0);
754e5da2
SG
1743 interp = Tcl_CreateInterp ();
1744
1745 if (!interp)
1746 error ("Tcl_CreateInterp failed");
1747
754e5da2
SG
1748 if (Tcl_Init(interp) != TCL_OK)
1749 error ("Tcl_Init failed: %s", interp->result);
1750
9a2f9219 1751 make_final_cleanup (gdbtk_cleanup, NULL);
2476848a 1752
9a2f9219 1753 /* Initialize the Paths variable. */
74089546 1754 if (ide_initialize_paths (interp, "gdbtcl") != TCL_OK)
9a2f9219
ILT
1755 error ("ide_initialize_paths failed: %s", interp->result);
1756
018d76dd
KS
1757#ifdef IDE
1758 /* start-sanitize-ide */
2476848a
MH
1759 /* Find the directory where we expect to find idemanager. We ignore
1760 errors since it doesn't really matter if this fails. */
1761 libexecdir = Tcl_GetVar2 (interp, "Paths", "libexecdir", TCL_GLOBAL_ONLY);
1762
1763 IluTk_Init ();
1764
7b94b2ea 1765 h = ide_event_init_from_environment (&errmsg, libexecdir);
2476848a
MH
1766 if (h == NULL)
1767 {
1768 Tcl_AppendResult (interp, "can't initialize event system: ", errmsg,
1769 (char *) NULL);
1770 fprintf(stderr, "WARNING: ide_event_init_client failed: %s\n", interp->result);
9a2f9219
ILT
1771
1772 Tcl_SetVar (interp, "GDBTK_IDE", "0", 0);
2476848a
MH
1773 }
1774 else
1775 {
1776 if (ide_create_tclevent_command (interp, h) != TCL_OK)
1777 error ("ide_create_tclevent_command failed: %s", interp->result);
018d76dd 1778
2476848a
MH
1779 if (ide_create_edit_command (interp, h) != TCL_OK)
1780 error ("ide_create_edit_command failed: %s", interp->result);
1781
1782 if (ide_create_property_command (interp, h) != TCL_OK)
1783 error ("ide_create_property_command failed: %s", interp->result);
018d76dd
KS
1784
1785 if (ide_create_build_command (interp, h) != TCL_OK)
1786 error ("ide_create_build_command failed: %s", interp->result);
1787
1788 if (ide_create_window_register_command (interp, h, "gdb-restore")
1789 != TCL_OK)
9a2f9219
ILT
1790 error ("ide_create_window_register_command failed: %s",
1791 interp->result);
1792
1793 if (ide_create_window_command (interp, h) != TCL_OK)
1794 error ("ide_create_window_command failed: %s", interp->result);
1795
018d76dd
KS
1796 if (ide_create_exit_command (interp, h) != TCL_OK)
1797 error ("ide_create_exit_command failed: %s", interp->result);
1798
1799 if (ide_create_help_command (interp) != TCL_OK)
1800 error ("ide_create_help_command failed: %s", interp->result);
1801
2476848a
MH
1802 /*
1803 if (ide_initialize (interp, "gdb") != TCL_OK)
1804 error ("ide_initialize failed: %s", interp->result);
1805 */
9a2f9219
ILT
1806
1807 Tcl_SetVar (interp, "GDBTK_IDE", "1", 0);
018d76dd 1808 Tcl_SetVar (interp, "IDE", "1", TCL_GLOBAL_ONLY);
2476848a 1809 }
018d76dd 1810 /* end-sanitize-ide */
2476848a
MH
1811#else
1812 Tcl_SetVar (interp, "GDBTK_IDE", "0", 0);
1813#endif /* IDE */
1814
9a2f9219
ILT
1815 /* We don't want to open the X connection until we've done all the
1816 IDE initialization. Otherwise, goofy looking unfinished windows
1817 pop up when ILU drops into the TCL event loop. */
1818
1819 if (Tk_Init(interp) != TCL_OK)
1820 error ("Tk_Init failed: %s", interp->result);
1821
1822 if (Itcl_Init(interp) == TCL_ERROR)
1823 error ("Itcl_Init failed: %s", interp->result);
1824
1825 if (Tix_Init(interp) != TCL_OK)
1826 error ("Tix_Init failed: %s", interp->result);
1827
018d76dd
KS
1828#ifdef __CYGWIN32__
1829 /* On Windows, create a sizebox widget command */
1830 if (ide_create_sizebox_command (interp) != TCL_OK)
1831 error ("sizebox creation failed");
1832 if (ide_create_winprint_command (interp) != TCL_OK)
1833 error ("windows print code initialization failed");
1834 /* start-sanitize-ide */
1835 /* An interface to ShellExecute. */
1836 if (ide_create_shell_execute_command (interp) != TCL_OK)
1837 error ("shell execute command initialization failed");
1838#endif
1839
86db943c
SG
1840 Tcl_CreateCommand (interp, "gdb_cmd", call_wrapper, gdb_cmd, NULL);
1841 Tcl_CreateCommand (interp, "gdb_loc", call_wrapper, gdb_loc, NULL);
8a19b35a 1842 Tcl_CreateCommand (interp, "gdb_path_conv", call_wrapper, gdb_path_conv, NULL);
86db943c
SG
1843 Tcl_CreateCommand (interp, "gdb_sourcelines", call_wrapper, gdb_sourcelines,
1844 NULL);
1845 Tcl_CreateCommand (interp, "gdb_listfiles", call_wrapper, gdb_listfiles,
746d1df4 1846 NULL);
99c98415
MH
1847 Tcl_CreateCommand (interp, "gdb_listfuncs", call_wrapper, gdb_listfuncs,
1848 NULL);
018d76dd
KS
1849 Tcl_CreateCommand (interp, "gdb_get_mem", call_wrapper, gdb_get_mem,
1850 NULL);
86db943c
SG
1851 Tcl_CreateCommand (interp, "gdb_stop", call_wrapper, gdb_stop, NULL);
1852 Tcl_CreateCommand (interp, "gdb_regnames", call_wrapper, gdb_regnames, NULL);
1853 Tcl_CreateCommand (interp, "gdb_fetch_registers", call_wrapper,
1854 gdb_fetch_registers, NULL);
1855 Tcl_CreateCommand (interp, "gdb_changed_register_list", call_wrapper,
1856 gdb_changed_register_list, NULL);
09722039
SG
1857 Tcl_CreateCommand (interp, "gdb_disassemble", call_wrapper,
1858 gdb_disassemble, NULL);
1859 Tcl_CreateCommand (interp, "gdb_eval", call_wrapper, gdb_eval, NULL);
6131622e
SG
1860 Tcl_CreateCommand (interp, "gdb_get_breakpoint_list", call_wrapper,
1861 gdb_get_breakpoint_list, NULL);
1862 Tcl_CreateCommand (interp, "gdb_get_breakpoint_info", call_wrapper,
1863 gdb_get_breakpoint_info, NULL);
018d76dd
KS
1864 Tcl_CreateCommand (interp, "gdb_clear_file", call_wrapper,
1865 gdb_clear_file, NULL);
1866 Tcl_CreateCommand (interp, "gdb_confirm_quit", call_wrapper,
1867 gdb_confirm_quit, NULL);
1868 Tcl_CreateCommand (interp, "gdb_force_quit", call_wrapper,
1869 gdb_force_quit, NULL);
1870 Tcl_CreateCommand (interp, "gdb_target_has_execution",
1871 gdb_target_has_execution_command,
1872 NULL, NULL);
1873 Tcl_CreateObjCommand (interp, "gdb_load_info", gdb_load_info, NULL, NULL);
1874 Tcl_CreateObjCommand (interp, "gdb_get_locals", gdb_get_vars_command,
1875 (ClientData) 0, NULL);
1876 Tcl_CreateObjCommand (interp, "gdb_get_args", gdb_get_vars_command,
1877 (ClientData) 1, NULL);
1878 Tcl_CreateObjCommand (interp, "gdb_get_function", gdb_get_function_command,
1879 NULL, NULL);
1880 Tcl_CreateObjCommand (interp, "gdb_get_line", gdb_get_line_command,
1881 NULL, NULL);
1882 Tcl_CreateObjCommand (interp, "gdb_get_file", gdb_get_file_command,
1883 NULL, NULL);
1884 Tcl_CreateObjCommand (interp, "gdb_tracepoint_exists",
1885 gdb_tracepoint_exists_command, NULL, NULL);
1886 Tcl_CreateObjCommand (interp, "gdb_get_tracepoint_info",
1887 gdb_get_tracepoint_info, NULL, NULL);
1888 Tcl_CreateObjCommand (interp, "gdb_actions",
1889 gdb_actions_command, NULL, NULL);
1890 Tcl_CreateObjCommand (interp, "gdb_prompt",
1891 gdb_prompt_command, NULL, NULL);
1892
5bac2b50 1893 command_loop_hook = tk_command_loop;
b607efe7
FF
1894 print_frame_info_listing_hook =
1895 (void (*) PARAMS ((struct symtab *, int, int, int))) null_routine;
09722039
SG
1896 query_hook = gdbtk_query;
1897 flush_hook = gdbtk_flush;
1898 create_breakpoint_hook = gdbtk_create_breakpoint;
1899 delete_breakpoint_hook = gdbtk_delete_breakpoint;
6131622e 1900 modify_breakpoint_hook = gdbtk_modify_breakpoint;
09722039
SG
1901 interactive_hook = gdbtk_interactive;
1902 target_wait_hook = gdbtk_wait;
1903 call_command_hook = gdbtk_call_command;
41756e56
FF
1904 readline_begin_hook = gdbtk_readline_begin;
1905 readline_hook = gdbtk_readline;
1906 readline_end_hook = gdbtk_readline_end;
018d76dd
KS
1907 ui_load_progress_hook = gdbtk_load_hash;
1908 create_tracepoint_hook = gdbtk_create_tracepoint;
1909 delete_tracepoint_hook = gdbtk_delete_tracepoint;
754e5da2 1910
018d76dd 1911#ifndef WINNT
cd2df226 1912 /* Get the file descriptor for the X server */
479f0f18 1913
047465fd 1914 x_fd = ConnectionNumber (Tk_Display (Tk_MainWindow (interp)));
479f0f18
SG
1915
1916 /* Setup for I/O interrupts */
1917
736a82e7
SG
1918 action.sa_mask = nullsigmask;
1919 action.sa_flags = 0;
1920 action.sa_handler = SIG_IGN;
1921 sigaction(SIGIO, &action, NULL);
1922
1923#ifdef FIOASYNC
1924 i = 1;
1925 if (ioctl (x_fd, FIOASYNC, &i))
1926 perror_with_name ("gdbtk_init: ioctl FIOASYNC failed");
479f0f18 1927
77a89957 1928#ifdef SIOCSPGRP
736a82e7
SG
1929 i = getpid();
1930 if (ioctl (x_fd, SIOCSPGRP, &i))
1931 perror_with_name ("gdbtk_init: ioctl SIOCSPGRP failed");
45f90c50
MM
1932
1933#else
1934#ifdef F_SETOWN
1935 i = getpid();
1936 if (fcntl (x_fd, F_SETOWN, i))
1937 perror_with_name ("gdbtk_init: fcntl F_SETOWN failed");
1938#endif /* F_SETOWN */
1939#endif /* !SIOCSPGRP */
546b8ca7 1940#else
8a19b35a 1941#ifndef WINNT
546b8ca7 1942 if (ioctl (x_fd, I_SETSIG, S_INPUT|S_RDNORM) < 0)
736a82e7 1943 perror_with_name ("gdbtk_init: ioctl I_SETSIG failed");
8a19b35a
MH
1944#endif
1945
736a82e7 1946#endif /* ifndef FIOASYNC */
018d76dd 1947#endif /* WINNT */
479f0f18 1948
754e5da2
SG
1949 add_com ("tk", class_obscure, tk_command,
1950 "Send a command directly into tk.");
09722039 1951
09722039
SG
1952 Tcl_LinkVar (interp, "disassemble-from-exec", (char *)&disassemble_from_exec,
1953 TCL_LINK_INT);
1954
8a19b35a 1955 /* find the gdb tcl library and source main.tcl */
09722039 1956
8a19b35a
MH
1957 gdbtk_lib = getenv ("GDBTK_LIBRARY");
1958 if (!gdbtk_lib)
1959 if (access ("gdbtcl/main.tcl", R_OK) == 0)
1960 gdbtk_lib = "gdbtcl";
09722039 1961 else
8a19b35a
MH
1962 gdbtk_lib = GDBTK_LIBRARY;
1963
74089546
ILT
1964 gdbtk_lib_tmp = xstrdup (gdbtk_lib);
1965
8a19b35a
MH
1966 found_main = 0;
1967 /* see if GDBTK_LIBRARY is a path list */
1968 lib = strtok (gdbtk_lib_tmp, GDBTK_PATH_SEP);
1969 do
1970 {
1971 if (Tcl_VarEval (interp, "lappend auto_path ", lib, NULL) != TCL_OK)
1972 {
1973 fputs_unfiltered (Tcl_GetVar (interp, "errorInfo", 0), gdb_stderr);
1974 error ("");
1975 }
1976 if (!found_main)
1977 {
74089546 1978 gdbtk_file = concat (lib, "/main.tcl", (char *) NULL);
8a19b35a
MH
1979 if (access (gdbtk_file, R_OK) == 0)
1980 {
1981 found_main++;
1982 Tcl_SetVar (interp, "GDBTK_LIBRARY", lib, 0);
1983 }
1984 }
1985 }
56e327b3 1986 while ((lib = strtok (NULL, ":")) != NULL);
74089546
ILT
1987
1988 free (gdbtk_lib_tmp);
1989
74089546
ILT
1990 if (!found_main)
1991 {
1992 /* Try finding it with the auto path. */
1993
1994 static const char script[] ="\
1995proc gdbtk_find_main {} {\n\
1996 global auto_path GDBTK_LIBRARY\n\
1997 foreach dir $auto_path {\n\
1998 set f [file join $dir main.tcl]\n\
1999 if {[file exists $f]} then {\n\
2000 set GDBTK_LIBRARY $dir\n\
2001 return $f\n\
2002 }\n\
2003 }\n\
2004 return ""\n\
2005}\n\
2006gdbtk_find_main";
2007
2008 if (Tcl_GlobalEval (interp, (char *) script) != TCL_OK)
2009 {
2010 fputs_unfiltered (Tcl_GetVar (interp, "errorInfo", 0), gdb_stderr);
2011 error ("");
2012 }
2013
2014 if (interp->result[0] != '\0')
2015 {
2016 gdbtk_file = xstrdup (interp->result);
2017 found_main++;
2018 }
2019 }
74089546 2020
8a19b35a
MH
2021 if (!found_main)
2022 {
2023 fputs_unfiltered_hook = NULL; /* Force errors to stdout/stderr */
2024 if (getenv("GDBTK_LIBRARY"))
2025 {
2026 fprintf_unfiltered (stderr, "Unable to find main.tcl in %s\n",getenv("GDBTK_LIBRARY"));
2027 fprintf_unfiltered (stderr,
2028 "Please set GDBTK_LIBRARY to a path that includes the GDB tcl files.\n");
2029 }
2030 else
2031 {
2032 fprintf_unfiltered (stderr, "Unable to find main.tcl in %s\n", GDBTK_LIBRARY);
2033 fprintf_unfiltered (stderr, "You might want to set GDBTK_LIBRARY\n");
2034 }
2035 error("");
2036 }
09722039 2037
724498fd
SG
2038/* Defer setup of fputs_unfiltered_hook to near the end so that error messages
2039 prior to this point go to stdout/stderr. */
2040
2041 fputs_unfiltered_hook = gdbtk_fputs;
2042
8a19b35a 2043 if (Tcl_EvalFile (interp, gdbtk_file) != TCL_OK)
724498fd 2044 {
018d76dd
KS
2045 char *msg;
2046
2047 /* Force errorInfo to be set up propertly. */
2048 Tcl_AddErrorInfo (interp, "");
2049
2050 msg = Tcl_GetVar (interp, "errorInfo", TCL_GLOBAL_ONLY);
2051
724498fd
SG
2052 fputs_unfiltered_hook = NULL; /* Force errors to stdout/stderr */
2053
018d76dd
KS
2054#ifdef _WIN32
2055 MessageBox (NULL, msg, NULL, MB_OK | MB_ICONERROR | MB_TASKMODAL);
2056#else
2057 fputs_unfiltered (msg, gdb_stderr);
2058#endif
b66051ec 2059
b66051ec 2060 error ("");
724498fd 2061 }
09722039 2062
018d76dd
KS
2063#ifdef IDE
2064 /* start-sanitize-ide */
2065 /* Don't do this until we have initialized. Otherwise, we may get a
2066 run command before we are ready for one. */
2067 if (ide_run_server_init (interp, h) != TCL_OK)
2068 error ("ide_run_server_init failed: %s", interp->result);
2069 /* end-sanitize-ide */
2070#endif
2071
74089546
ILT
2072 free (gdbtk_file);
2073
09722039 2074 discard_cleanups (old_chain);
754e5da2
SG
2075}
2076
018d76dd
KS
2077static int
2078gdb_target_has_execution_command (clientData, interp, argc, argv)
2079 ClientData clientData;
2080 Tcl_Interp *interp;
2081 int argc;
2082 char *argv[];
2083{
2084 int result = 0;
2085
2086 if (target_has_execution && inferior_pid != 0)
2087 result = 1;
2088
2089 Tcl_SetIntObj (Tcl_GetObjResult (interp), result);
2090 return TCL_OK;
2091}
2092
2093/* gdb_load_info - returns information about the file about to be downloaded */
2094
2095static int
2096gdb_load_info (clientData, interp, objc, objv)
2097 ClientData clientData;
2098 Tcl_Interp *interp;
2099 int objc;
2100 Tcl_Obj *CONST objv[];
2101{
2102 bfd *loadfile_bfd;
2103 struct cleanup *old_cleanups;
2104 asection *s;
2105 Tcl_Obj *ob[2];
2106 Tcl_Obj *res[16];
2107 int i = 0;
2108
2109 char *filename = Tcl_GetStringFromObj (objv[1], NULL);
2110
2111 loadfile_bfd = bfd_openr (filename, gnutarget);
2112 if (loadfile_bfd == NULL)
2113 {
2114 Tcl_SetObjResult (interp, Tcl_NewStringObj ("Open failed", -1));
2115 return TCL_ERROR;
2116 }
2117 old_cleanups = make_cleanup (bfd_close, loadfile_bfd);
2118
2119 if (!bfd_check_format (loadfile_bfd, bfd_object))
2120 {
2121 Tcl_SetObjResult (interp, Tcl_NewStringObj ("Bad Object File", -1));
2122 return TCL_ERROR;
2123 }
2124
2125 for (s = loadfile_bfd->sections; s; s = s->next)
2126 {
2127 if (s->flags & SEC_LOAD)
2128 {
2129 bfd_size_type size = bfd_get_section_size_before_reloc (s);
2130 if (size > 0)
2131 {
2132 ob[0] = Tcl_NewStringObj((char *)bfd_get_section_name(loadfile_bfd, s), -1);
2133 ob[1] = Tcl_NewLongObj ((long)size);
2134 res[i++] = Tcl_NewListObj (2, ob);
2135 }
2136 }
2137 }
2138
2139 Tcl_SetObjResult (interp, Tcl_NewListObj (i, res));
2140 do_cleanups (old_cleanups);
2141 return TCL_OK;
2142}
2143
2144
2145int
2146gdbtk_load_hash (section, num)
2147 char *section;
2148 unsigned long num;
2149{
2150 int result;
2151 char buf[128];
2152 sprintf (buf, "download_hash %s %ld", section, num);
2153 result = Tcl_Eval (interp, buf);
2154 return result;
2155}
2156
2157/* gdb_get_vars_command -
2158 *
2159 * Implements the "gdb_get_locals" and "gdb_get_args" tcl commands. This
2160 * function sets the Tcl interpreter's result to a list of variable names
2161 * depending on clientData. If clientData is one, the result is a list of
2162 * arguments; zero returns a list of locals -- all relative to the block
2163 * specified as an argument to the command. Valid commands include
2164 * anything decode_line_1 can handle (like "main.c:2", "*0x02020202",
2165 * and "main").
2166 */
2167static int
2168gdb_get_vars_command (clientData, interp, objc, objv)
2169 ClientData clientData;
2170 Tcl_Interp *interp;
2171 int objc;
2172 Tcl_Obj *CONST objv[];
2173{
2174 Tcl_Obj *result;
2175 struct symtabs_and_lines sals;
2176 struct symbol *sym;
2177 struct block *block;
2178 char **canonical, *args;
2179 int i, nsyms, arguments;
2180
2181 if (objc != 2)
2182 {
2183 Tcl_AppendResult (interp,
2184 "wrong # of args: should be \"",
2185 Tcl_GetStringFromObj (objv[0], NULL),
2186 " function:line|function|line|*addr\"");
2187 return TCL_ERROR;
2188 }
2189
2190 arguments = (int) clientData;
2191 args = Tcl_GetStringFromObj (objv[1], NULL);
2192 sals = decode_line_1 (&args, 1, NULL, 0, &canonical);
2193 if (sals.nelts == 0)
2194 {
2195 Tcl_AppendResult (interp,
2196 "error decoding line", NULL);
2197 return TCL_ERROR;
2198 }
2199
2200 /* Initialize a list that will hold the results */
2201 result = Tcl_NewListObj (0, NULL);
2202
2203 /* Resolve all line numbers to PC's */
2204 for (i = 0; i < sals.nelts; i++)
2205 resolve_sal_pc (&sals.sals[i]);
2206
2207 block = block_for_pc (sals.sals[0].pc);
2208 while (block != 0)
2209 {
2210 nsyms = BLOCK_NSYMS (block);
2211 for (i = 0; i < nsyms; i++)
2212 {
2213 sym = BLOCK_SYM (block, i);
2214 switch (SYMBOL_CLASS (sym)) {
2215 default:
2216 case LOC_UNDEF: /* catches errors */
2217 case LOC_CONST: /* constant */
2218 case LOC_STATIC: /* static */
2219 case LOC_REGISTER: /* register */
2220 case LOC_TYPEDEF: /* local typedef */
2221 case LOC_LABEL: /* local label */
2222 case LOC_BLOCK: /* local function */
2223 case LOC_CONST_BYTES: /* loc. byte seq. */
2224 case LOC_UNRESOLVED: /* unresolved static */
2225 case LOC_OPTIMIZED_OUT: /* optimized out */
2226 break;
2227 case LOC_ARG: /* argument */
2228 case LOC_REF_ARG: /* reference arg */
2229 case LOC_REGPARM: /* register arg */
2230 case LOC_REGPARM_ADDR: /* indirect register arg */
2231 case LOC_LOCAL_ARG: /* stack arg */
2232 case LOC_BASEREG_ARG: /* basereg arg */
2233 if (arguments)
2234 Tcl_ListObjAppendElement (interp, result,
2235 Tcl_NewStringObj (SYMBOL_NAME (sym), -1));
2236 break;
2237 case LOC_LOCAL: /* stack local */
2238 case LOC_BASEREG: /* basereg local */
2239 if (!arguments)
2240 Tcl_ListObjAppendElement (interp, result,
2241 Tcl_NewStringObj (SYMBOL_NAME (sym), -1));
2242 break;
2243 }
2244 }
2245 if (BLOCK_FUNCTION (block))
2246 break;
2247 else
2248 block = BLOCK_SUPERBLOCK (block);
2249 }
2250
2251 Tcl_SetObjResult (interp, result);
2252 return TCL_OK;
2253}
2254
2255static int
2256gdb_get_line_command (clientData, interp, objc, objv)
2257 ClientData clientData;
2258 Tcl_Interp *interp;
2259 int objc;
2260 Tcl_Obj *CONST objv[];
2261{
2262 Tcl_Obj *result;
2263 struct symtabs_and_lines sals;
2264 char *args, **canonical;
2265
2266 if (objc != 2)
2267 {
2268 Tcl_AppendResult (interp, "wrong # of args: should be \"",
2269 Tcl_GetStringFromObj (objv[0], NULL),
2270 " linespec\"");
2271 return TCL_ERROR;
2272 }
2273
2274 args = Tcl_GetStringFromObj (objv[1], NULL);
2275 sals = decode_line_1 (&args, 1, NULL, 0, &canonical);
2276 if (sals.nelts == 1)
2277 {
2278 Tcl_SetObjResult (interp, Tcl_NewIntObj (sals.sals[0].line));
2279 return TCL_OK;
2280 }
2281
2282 Tcl_SetResult (interp, "N/A", TCL_STATIC);
2283 return TCL_OK;
2284}
2285
2286static int
2287gdb_get_file_command (clientData, interp, objc, objv)
2288 ClientData clientData;
2289 Tcl_Interp *interp;
2290 int objc;
2291 Tcl_Obj *CONST objv[];
2292{
2293 Tcl_Obj *result;
2294 struct symtabs_and_lines sals;
2295 char *args, **canonical;
2296
2297 if (objc != 2)
2298 {
2299 Tcl_AppendResult (interp, "wrong # of args: should be \"",
2300 Tcl_GetStringFromObj (objv[0], NULL),
2301 " linespec\"");
2302 return TCL_ERROR;
2303 }
2304
2305 args = Tcl_GetStringFromObj (objv[1], NULL);
2306 sals = decode_line_1 (&args, 1, NULL, 0, &canonical);
2307 if (sals.nelts == 1)
2308 {
2309 Tcl_SetResult (interp, sals.sals[0].symtab->filename, TCL_VOLATILE);
2310 return TCL_OK;
2311 }
2312
2313 Tcl_SetResult (interp, "N/A", TCL_STATIC);
2314 return TCL_OK;
2315}
2316
2317static int
2318gdb_get_function_command (clientData, interp, objc, objv)
2319 ClientData clientData;
2320 Tcl_Interp *interp;
2321 int objc;
2322 Tcl_Obj *CONST objv[];
2323{
2324 Tcl_Obj *result;
2325 char *function;
2326 struct symtabs_and_lines sals;
2327 char *args, **canonical;
2328
2329 if (objc != 2)
2330 {
2331 Tcl_AppendResult (interp, "wrong # of args: should be \"",
2332 Tcl_GetStringFromObj (objv[0], NULL),
2333 " linespec\"");
2334 return TCL_ERROR;
2335 }
2336
2337 args = Tcl_GetStringFromObj (objv[1], NULL);
2338 sals = decode_line_1 (&args, 1, NULL, 0, &canonical);
2339 if (sals.nelts == 1)
2340 {
2341 resolve_sal_pc (&sals.sals[0]);
2342 find_pc_partial_function (sals.sals[0].pc, &function, NULL, NULL);
2343 if (function != NULL)
2344 {
2345 Tcl_SetResult (interp, function, TCL_VOLATILE);
2346 return TCL_OK;
2347 }
2348 }
2349
2350 Tcl_SetResult (interp, "N/A", TCL_STATIC);
2351 return TCL_OK;
2352}
2353
2354static int
2355gdb_get_tracepoint_info (clientData, interp, objc, objv)
2356 ClientData clientData;
2357 Tcl_Interp *interp;
2358 int objc;
2359 Tcl_Obj *CONST objv[];
2360{
2361 struct symtab_and_line sal;
2362 struct command_line *cmd;
2363 int tpnum;
2364 struct tracepoint *tp;
2365 struct action_line *al;
2366 Tcl_Obj *list, *action_list;
2367 char tmp[19];
2368
2369 if (objc != 2)
2370 error ("wrong # args");
2371
2372 Tcl_GetIntFromObj (NULL, objv[1], &tpnum);
2373
2374 ALL_TRACEPOINTS (tp)
2375 if (tp->number == tpnum)
2376 break;
2377
2378 if (tp == NULL)
2379 error ("Tracepoint #%d does not exist", tpnum);
2380
2381 list = Tcl_NewListObj (0, NULL);
2382 if (tp->source_file != NULL)
2383 Tcl_ListObjAppendElement (interp, list, Tcl_NewStringObj (tp->source_file, -1));
2384 else
2385 Tcl_ListObjAppendElement (interp, list, Tcl_NewStringObj ("N/A", -1));
2386 Tcl_ListObjAppendElement (interp, list, Tcl_NewIntObj (tp->line_number));
2387 /* the function part is not currently used by the frontend */
2388 Tcl_ListObjAppendElement (interp, list, Tcl_NewStringObj ("function", -1));
2389 sprintf (tmp, "0x%08x", tp->address);
2390 Tcl_ListObjAppendElement (interp, list, Tcl_NewStringObj (tmp, -1));
2391 Tcl_ListObjAppendElement (interp, list, Tcl_NewIntObj (tp->enabled));
2392 Tcl_ListObjAppendElement (interp, list, Tcl_NewIntObj (tp->pass_count));
2393 Tcl_ListObjAppendElement (interp, list, Tcl_NewIntObj (tp->step_count));
2394 Tcl_ListObjAppendElement (interp, list, Tcl_NewIntObj (tp->thread));
2395 Tcl_ListObjAppendElement (interp, list, Tcl_NewIntObj (tp->hit_count));
2396
2397 /* Append a list of actions */
2398 action_list = Tcl_NewListObj (0, NULL);
2399 for (al = tp->actions; al != NULL; al = al->next)
2400 {
2401 Tcl_ListObjAppendElement (interp, action_list,
2402 Tcl_NewStringObj (al->action, -1));
2403 }
2404 Tcl_ListObjAppendElement (interp, list, action_list);
2405
2406 Tcl_SetObjResult (interp, list);
2407 return TCL_OK;
2408}
2409
2410static void
2411gdbtk_create_tracepoint (tp)
2412 struct tracepoint *tp;
2413{
2414 tracepoint_notify (tp, "create");
2415}
2416
2417static void
2418gdbtk_delete_tracepoint (tp)
2419 struct tracepoint *tp;
2420{
2421 tracepoint_notify (tp, "delete");
2422}
2423
2424static void
2425tracepoint_notify(tp, action)
2426 struct tracepoint *tp;
2427 const char *action;
2428{
2429 char buf[256];
2430 char *source;
2431 int v;
2432
2433 /* We ensure that ACTION contains no special Tcl characters, so we
2434 can do this. */
2435 if (tp->source_file != NULL)
2436 source = tp->source_file;
2437 else
2438 source = "N/A";
2439 sprintf (buf, "gdbtk_tcl_tracepoint %s %d 0x%lx %d {%s}", action, tp->number,
2440 (long)tp->address, tp->line_number, source);
2441
2442 v = Tcl_Eval (interp, buf);
2443
2444 if (v != TCL_OK)
2445 {
2446 gdbtk_fputs (interp->result, gdb_stdout);
2447 gdbtk_fputs ("\n", gdb_stdout);
2448 }
2449}
2450
2451/* returns -1 if not found, tracepoint # if found */
2452int
2453tracepoint_exists (char * args)
2454{
2455 struct tracepoint *tp;
2456 char **canonical;
2457 struct symtabs_and_lines sals;
2458 char *file = NULL;
2459 int result = -1;
2460
2461 sals = decode_line_1 (&args, 1, NULL, 0, &canonical);
2462 if (sals.nelts == 1)
2463 {
2464 resolve_sal_pc (&sals.sals[0]);
2465 file = xmalloc (strlen (sals.sals[0].symtab->dirname)
2466 + strlen (sals.sals[0].symtab->filename) + 1);
2467 if (file != NULL)
2468 {
2469 strcpy (file, sals.sals[0].symtab->dirname);
2470 strcat (file, sals.sals[0].symtab->filename);
2471
2472 ALL_TRACEPOINTS (tp)
2473 {
2474 if (tp->address == sals.sals[0].pc)
2475 result = tp->number;
2476 else if (tp->source_file != NULL
2477 && strcmp (tp->source_file, file) == 0
2478 && sals.sals[0].line == tp->line_number)
2479
2480 result = tp->number;
2481 }
2482 }
2483 }
2484 if (file != NULL)
2485 free (file);
2486 return result;
2487}
2488
2489static int
2490gdb_actions_command (clientData, interp, objc, objv)
2491 ClientData clientData;
2492 Tcl_Interp *interp;
2493 int objc;
2494 Tcl_Obj *CONST objv[];
2495{
2496 struct tracepoint *tp;
2497 Tcl_Obj **actions;
2498 int nactions, i, len;
2499 char *number, *args, *action;
2500 struct action_line *next = NULL, *temp;
2501
2502 if (objc != 3)
2503 {
2504 Tcl_AppendResult (interp, "wrong # args: should be: \"",
2505 Tcl_GetStringFromObj (objv[0], NULL),
2506 " number actions\"");
2507 return TCL_ERROR;
2508 }
2509
2510 args = number = Tcl_GetStringFromObj (objv[1], NULL);
2511 tp = get_tracepoint_by_number (&args);
2512 if (tp == NULL)
2513 {
2514 Tcl_AppendResult (interp, "Tracepoint \"", number, "\" does not exist");
2515 return TCL_ERROR;
2516 }
2517
2518 /* Free any existing actions */
2519 for (temp = tp->actions; temp != NULL; temp = temp->next)
2520 {
2521 if (temp->action)
2522 free (temp->action);
2523 free (temp);
2524 }
2525
2526 Tcl_ListObjGetElements (interp, objv[2], &nactions, &actions);
2527 for (i = 0; i < nactions; i++)
2528 {
2529 temp = xmalloc (sizeof (struct action_line));
2530 temp->next = NULL;
2531 action = Tcl_GetStringFromObj (actions[i], &len);
2532 temp->action = savestring (action, len);
2533 if (next == NULL)
2534 {
2535 tp->actions = temp;
2536 next = temp;
2537 }
2538 else
2539 {
2540 next->next = temp;
2541 next = temp;
2542 }
2543 }
2544
2545 return TCL_OK;
2546}
2547
2548static int
2549gdb_tracepoint_exists_command (clientData, interp, objc, objv)
2550 ClientData clientData;
2551 Tcl_Interp *interp;
2552 int objc;
2553 Tcl_Obj *CONST objv[];
2554{
2555 char * args;
2556
2557 if (objc != 2)
2558 {
2559 Tcl_AppendResult (interp, "wrong # of args: should be \"",
2560 Tcl_GetStringFromObj (objv[0], NULL),
2561 " function:line|function|line|*addr\"");
2562 return TCL_ERROR;
2563 }
2564
2565 args = Tcl_GetStringFromObj (objv[1], NULL);
2566
2567 Tcl_SetObjResult (interp, Tcl_NewIntObj (tracepoint_exists (args)));
2568 return TCL_OK;
2569}
2570
2571/* Return the prompt to the interpreter */
2572static int
2573gdb_prompt_command (clientData, interp, objc, objv)
2574 ClientData clientData;
2575 Tcl_Interp *interp;
2576 int objc;
2577 Tcl_Obj *CONST objv[];
2578{
2579 Tcl_SetResult (interp, get_prompt (), TCL_VOLATILE);
2580 return TCL_OK;
2581}
2582
3f37b696 2583/* Come here during initialize_all_files () */
754e5da2
SG
2584
2585void
2586_initialize_gdbtk ()
2587{
c5197511
SG
2588 if (use_windows)
2589 {
2590 /* Tell the rest of the world that Gdbtk is now set up. */
754e5da2 2591
c5197511
SG
2592 init_ui_hook = gdbtk_init;
2593 }
754e5da2 2594}
This page took 0.261278 seconds and 4 git commands to generate.