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