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