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