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