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