Replace "exec" with "executable" in messages.
[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 {
671 result_ptr->flags &= ~GDBTK_TO_RESULT;
672 load_in_progress = 1;
673 }
674
675 execute_command (Tcl_GetStringFromObj (objv[1], NULL), 1);
676
677 if (load_in_progress)
678 {
679 load_in_progress = 0;
680 result_ptr->flags |= GDBTK_TO_RESULT;
681 }
682
683 bpstat_do_actions (&stop_bpstat);
684
685 return TCL_OK;
686 }
687
688 /*
689 * This implements the tcl command "gdb_immediate"
690 *
691 * It does exactly the same thing as gdb_cmd, except NONE of its outut
692 * is buffered. This will also ALWAYS cause the busy, update, and idle hooks to
693 * be called, contrasted with gdb_cmd, which NEVER calls them.
694 * It turns off the GDBTK_TO_RESULT flag, which diverts the result
695 * to the console window.
696 *
697 * Tcl Arguments:
698 * command - The GDB command to execute
699 * Tcl Result:
700 * None.
701 */
702
703 static int
704 gdb_immediate_command (clientData, interp, objc, objv)
705 ClientData clientData;
706 Tcl_Interp *interp;
707 int objc;
708 Tcl_Obj *CONST objv[];
709 {
710
711 if (objc != 2)
712 {
713 Tcl_SetStringObj (result_ptr->obj_ptr, "wrong # args", -1);
714 return TCL_ERROR;
715 }
716
717 if (running_now || load_in_progress)
718 return TCL_OK;
719
720 No_Update = 0;
721
722 result_ptr->flags &= ~GDBTK_TO_RESULT;
723
724 execute_command (Tcl_GetStringFromObj (objv[1], NULL), 1);
725
726 bpstat_do_actions (&stop_bpstat);
727
728 result_ptr->flags |= GDBTK_TO_RESULT;
729
730 return TCL_OK;
731 }
732
733 /* This implements the tcl command "gdb_prompt"
734 *
735 * It returns the gdb interpreter's prompt.
736 *
737 * Tcl Arguments:
738 * None.
739 * Tcl Result:
740 * The prompt.
741 */
742
743 static int
744 gdb_prompt_command (clientData, interp, objc, objv)
745 ClientData clientData;
746 Tcl_Interp *interp;
747 int objc;
748 Tcl_Obj *CONST objv[];
749 {
750 Tcl_SetStringObj (result_ptr->obj_ptr, get_prompt (), -1);
751 return TCL_OK;
752 }
753
754 \f
755 /*
756 * This section contains general informational commands.
757 */
758
759 /* This implements the tcl command "gdb_target_has_execution"
760 *
761 * Tells whether the target is executing.
762 *
763 * Tcl Arguments:
764 * None
765 * Tcl Result:
766 * A boolean indicating whether the target is executing.
767 */
768
769 static int
770 gdb_target_has_execution_command (clientData, interp, objc, objv)
771 ClientData clientData;
772 Tcl_Interp *interp;
773 int objc;
774 Tcl_Obj *CONST objv[];
775 {
776 int result = 0;
777
778 if (target_has_execution && inferior_pid != 0)
779 result = 1;
780
781 Tcl_SetBooleanObj (result_ptr->obj_ptr, result);
782 return TCL_OK;
783 }
784
785 /* This implements the tcl command "gdb_load_info"
786 *
787 * It returns information about the file about to be downloaded.
788 *
789 * Tcl Arguments:
790 * filename: The file to open & get the info on.
791 * Tcl Result:
792 * A list consisting of the name and size of each section.
793 */
794
795 static int
796 gdb_load_info (clientData, interp, objc, objv)
797 ClientData clientData;
798 Tcl_Interp *interp;
799 int objc;
800 Tcl_Obj *CONST objv[];
801 {
802 bfd *loadfile_bfd;
803 struct cleanup *old_cleanups;
804 asection *s;
805 Tcl_Obj *ob[2];
806
807 char *filename = Tcl_GetStringFromObj (objv[1], NULL);
808
809 loadfile_bfd = bfd_openr (filename, gnutarget);
810 if (loadfile_bfd == NULL)
811 {
812 Tcl_SetStringObj (result_ptr->obj_ptr, "Open failed", -1);
813 return TCL_ERROR;
814 }
815 old_cleanups = make_cleanup (bfd_close, loadfile_bfd);
816
817 if (!bfd_check_format (loadfile_bfd, bfd_object))
818 {
819 Tcl_SetStringObj (result_ptr->obj_ptr, "Bad Object File", -1);
820 return TCL_ERROR;
821 }
822
823 Tcl_SetListObj (result_ptr->obj_ptr, 0, NULL);
824
825 for (s = loadfile_bfd->sections; s; s = s->next)
826 {
827 if (s->flags & SEC_LOAD)
828 {
829 bfd_size_type size = bfd_get_section_size_before_reloc (s);
830 if (size > 0)
831 {
832 ob[0] = Tcl_NewStringObj ((char *) bfd_get_section_name (loadfile_bfd, s), -1);
833 ob[1] = Tcl_NewLongObj ((long) size);
834 Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, Tcl_NewListObj (2, ob));
835 }
836 }
837 }
838
839 do_cleanups (old_cleanups);
840 return TCL_OK;
841 }
842
843
844 /* gdb_get_locals -
845 * This and gdb_get_locals just call gdb_get_vars_command with the right
846 * value of clientData. We can't use the client data in the definition
847 * of the command, because the call wrapper uses this instead...
848 */
849
850 static int
851 gdb_get_locals_command (clientData, interp, objc, objv)
852 ClientData clientData;
853 Tcl_Interp *interp;
854 int objc;
855 Tcl_Obj *CONST objv[];
856 {
857
858 return gdb_get_vars_command((ClientData) 0, interp, objc, objv);
859
860 }
861
862 static int
863 gdb_get_args_command (clientData, interp, objc, objv)
864 ClientData clientData;
865 Tcl_Interp *interp;
866 int objc;
867 Tcl_Obj *CONST objv[];
868 {
869
870 return gdb_get_vars_command((ClientData) 1, interp, objc, objv);
871
872 }
873
874 /* This implements the tcl commands "gdb_get_locals" and "gdb_get_args"
875 *
876 * This function sets the Tcl interpreter's result to a list of variable names
877 * depending on clientData. If clientData is one, the result is a list of
878 * arguments; zero returns a list of locals -- all relative to the block
879 * specified as an argument to the command. Valid commands include
880 * anything decode_line_1 can handle (like "main.c:2", "*0x02020202",
881 * and "main").
882 *
883 * Tcl Arguments:
884 * block - the address within which to specify the locals or args.
885 * Tcl Result:
886 * A list of the locals or args
887 */
888
889 static int
890 gdb_get_vars_command (clientData, interp, objc, objv)
891 ClientData clientData;
892 Tcl_Interp *interp;
893 int objc;
894 Tcl_Obj *CONST objv[];
895 {
896 struct symtabs_and_lines sals;
897 struct symbol *sym;
898 struct block *block;
899 char **canonical, *args;
900 int i, nsyms, arguments;
901
902 if (objc != 2)
903 {
904 Tcl_AppendStringsToObj (result_ptr->obj_ptr,
905 "wrong # of args: should be \"",
906 Tcl_GetStringFromObj (objv[0], NULL),
907 " function:line|function|line|*addr\"", NULL);
908 return TCL_ERROR;
909 }
910
911 arguments = (int) clientData;
912 args = Tcl_GetStringFromObj (objv[1], NULL);
913 sals = decode_line_1 (&args, 1, NULL, 0, &canonical);
914 if (sals.nelts == 0)
915 {
916 Tcl_SetStringObj (result_ptr->obj_ptr,
917 "error decoding line", -1);
918 return TCL_ERROR;
919 }
920
921 /* Initialize the result pointer to an empty list. */
922
923 Tcl_SetListObj (result_ptr->obj_ptr, 0, NULL);
924
925 /* Resolve all line numbers to PC's */
926 for (i = 0; i < sals.nelts; i++)
927 resolve_sal_pc (&sals.sals[i]);
928
929 block = block_for_pc (sals.sals[0].pc);
930 while (block != 0)
931 {
932 nsyms = BLOCK_NSYMS (block);
933 for (i = 0; i < nsyms; i++)
934 {
935 sym = BLOCK_SYM (block, i);
936 switch (SYMBOL_CLASS (sym)) {
937 default:
938 case LOC_UNDEF: /* catches errors */
939 case LOC_CONST: /* constant */
940 case LOC_TYPEDEF: /* local typedef */
941 case LOC_LABEL: /* local label */
942 case LOC_BLOCK: /* local function */
943 case LOC_CONST_BYTES: /* loc. byte seq. */
944 case LOC_UNRESOLVED: /* unresolved static */
945 case LOC_OPTIMIZED_OUT: /* optimized out */
946 break;
947 case LOC_ARG: /* argument */
948 case LOC_REF_ARG: /* reference arg */
949 case LOC_REGPARM: /* register arg */
950 case LOC_REGPARM_ADDR: /* indirect register arg */
951 case LOC_LOCAL_ARG: /* stack arg */
952 case LOC_BASEREG_ARG: /* basereg arg */
953 if (arguments)
954 Tcl_ListObjAppendElement (interp, result_ptr->obj_ptr,
955 Tcl_NewStringObj (SYMBOL_NAME (sym), -1));
956 break;
957 case LOC_LOCAL: /* stack local */
958 case LOC_BASEREG: /* basereg local */
959 case LOC_STATIC: /* static */
960 case LOC_REGISTER: /* register */
961 if (!arguments)
962 Tcl_ListObjAppendElement (interp, result_ptr->obj_ptr,
963 Tcl_NewStringObj (SYMBOL_NAME (sym), -1));
964 break;
965 }
966 }
967 if (BLOCK_FUNCTION (block))
968 break;
969 else
970 block = BLOCK_SUPERBLOCK (block);
971 }
972
973 return TCL_OK;
974 }
975
976 /* This implements the tcl command "gdb_get_line"
977 *
978 * It returns the linenumber for a given linespec. It will take any spec
979 * that can be passed to decode_line_1
980 *
981 * Tcl Arguments:
982 * linespec - the line specification
983 * Tcl Result:
984 * The line number for that spec.
985 */
986 static int
987 gdb_get_line_command (clientData, interp, objc, objv)
988 ClientData clientData;
989 Tcl_Interp *interp;
990 int objc;
991 Tcl_Obj *CONST objv[];
992 {
993 struct symtabs_and_lines sals;
994 char *args, **canonical;
995
996 if (objc != 2)
997 {
998 Tcl_AppendStringsToObj (result_ptr->obj_ptr, "wrong # of args: should be \"",
999 Tcl_GetStringFromObj (objv[0], NULL),
1000 " linespec\"", NULL);
1001 return TCL_ERROR;
1002 }
1003
1004 args = Tcl_GetStringFromObj (objv[1], NULL);
1005 sals = decode_line_1 (&args, 1, NULL, 0, &canonical);
1006 if (sals.nelts == 1)
1007 {
1008 Tcl_SetIntObj (result_ptr->obj_ptr, sals.sals[0].line);
1009 return TCL_OK;
1010 }
1011
1012 Tcl_SetStringObj (result_ptr->obj_ptr, "N/A", -1);
1013 return TCL_OK;
1014
1015 }
1016
1017 /* This implements the tcl command "gdb_get_file"
1018 *
1019 * It returns the file containing a given line spec.
1020 *
1021 * Tcl Arguments:
1022 * linespec - The linespec to look up
1023 * Tcl Result:
1024 * The file containing it.
1025 */
1026
1027 static int
1028 gdb_get_file_command (clientData, interp, objc, objv)
1029 ClientData clientData;
1030 Tcl_Interp *interp;
1031 int objc;
1032 Tcl_Obj *CONST objv[];
1033 {
1034 struct symtabs_and_lines sals;
1035 char *args, **canonical;
1036
1037 if (objc != 2)
1038 {
1039 Tcl_AppendStringsToObj (result_ptr->obj_ptr, "wrong # of args: should be \"",
1040 Tcl_GetStringFromObj (objv[0], NULL),
1041 " linespec\"", NULL);
1042 return TCL_ERROR;
1043 }
1044
1045 args = Tcl_GetStringFromObj (objv[1], NULL);
1046 sals = decode_line_1 (&args, 1, NULL, 0, &canonical);
1047 if (sals.nelts == 1)
1048 {
1049 Tcl_SetStringObj (result_ptr->obj_ptr, sals.sals[0].symtab->filename, -1);
1050 return TCL_OK;
1051 }
1052
1053 Tcl_SetStringObj (result_ptr->obj_ptr, "N/A", -1);
1054 return TCL_OK;
1055 }
1056
1057 /* This implements the tcl command "gdb_get_function"
1058 *
1059 * It finds the function containing the given line spec.
1060 *
1061 * Tcl Arguments:
1062 * linespec - The line specification
1063 * Tcl Result:
1064 * The function that contains it, or "N/A" if it is not in a function.
1065 */
1066 static int
1067 gdb_get_function_command (clientData, interp, objc, objv)
1068 ClientData clientData;
1069 Tcl_Interp *interp;
1070 int objc;
1071 Tcl_Obj *CONST objv[];
1072 {
1073 char *function;
1074 struct symtabs_and_lines sals;
1075 char *args, **canonical;
1076
1077 if (objc != 2)
1078 {
1079 Tcl_AppendStringsToObj (result_ptr->obj_ptr, "wrong # of args: should be \"",
1080 Tcl_GetStringFromObj (objv[0], NULL),
1081 " linespec\"", NULL);
1082 return TCL_ERROR;
1083 }
1084
1085 args = Tcl_GetStringFromObj (objv[1], NULL);
1086 sals = decode_line_1 (&args, 1, NULL, 0, &canonical);
1087 if (sals.nelts == 1)
1088 {
1089 resolve_sal_pc (&sals.sals[0]);
1090 find_pc_partial_function (sals.sals[0].pc, &function, NULL, NULL);
1091 if (function != NULL)
1092 {
1093 Tcl_SetStringObj (result_ptr->obj_ptr, function, -1);
1094 return TCL_OK;
1095 }
1096 }
1097
1098 Tcl_SetStringObj (result_ptr->obj_ptr, "N/A", -1);
1099 return TCL_OK;
1100 }
1101
1102 /* This implements the tcl command "gdb_find_file"
1103 *
1104 * It searches the symbol tables to get the full pathname to a file.
1105 *
1106 * Tcl Arguments:
1107 * filename: the file name to search for.
1108 * Tcl Result:
1109 * The full path to the file, or an empty string if the file is not
1110 * found.
1111 */
1112
1113 static int
1114 gdb_find_file_command (clientData, interp, objc, objv)
1115 ClientData clientData;
1116 Tcl_Interp *interp;
1117 int objc;
1118 Tcl_Obj *CONST objv[];
1119 {
1120 char *filename = NULL;
1121 struct symtab *st;
1122
1123 if (objc != 2)
1124 {
1125 Tcl_WrongNumArgs(interp, 1, objv, "filename");
1126 return TCL_ERROR;
1127 }
1128
1129 st = full_lookup_symtab (Tcl_GetStringFromObj (objv[1], NULL));
1130 if (st)
1131 filename = st->fullname;
1132
1133 if (filename == NULL)
1134 Tcl_SetStringObj (result_ptr->obj_ptr, "", 0);
1135 else
1136 Tcl_SetStringObj (result_ptr->obj_ptr, filename, -1);
1137
1138 return TCL_OK;
1139 }
1140
1141 /* This implements the tcl command "gdb_listfiles"
1142 *
1143 * This lists all the files in the current executible.
1144 *
1145 * Note that this currently pulls in all sorts of filenames
1146 * that aren't really part of the executable. It would be
1147 * best if we could check each file to see if it actually
1148 * contains executable lines of code, but we can't do that
1149 * with psymtabs.
1150 *
1151 * Arguments:
1152 * ?pathname? - If provided, only files which match pathname
1153 * (up to strlen(pathname)) are included. THIS DOES NOT
1154 * CURRENTLY WORK BECAUSE PARTIAL_SYMTABS DON'T SUPPLY
1155 * THE FULL PATHNAME!!!
1156 *
1157 * Tcl Result:
1158 * A list of all matching files.
1159 */
1160 static int
1161 gdb_listfiles (clientData, interp, objc, objv)
1162 ClientData clientData;
1163 Tcl_Interp *interp;
1164 int objc;
1165 Tcl_Obj *CONST objv[];
1166 {
1167 struct objfile *objfile;
1168 struct partial_symtab *psymtab;
1169 struct symtab *symtab;
1170 char *lastfile, *pathname=NULL, **files;
1171 int files_size;
1172 int i, numfiles = 0, len = 0;
1173
1174 files_size = 1000;
1175 files = (char **) xmalloc (sizeof (char *) * files_size);
1176
1177 if (objc > 2)
1178 {
1179 Tcl_WrongNumArgs (interp, 1, objv, "Usage: gdb_listfiles ?pathname?");
1180 return TCL_ERROR;
1181 }
1182 else if (objc == 2)
1183 pathname = Tcl_GetStringFromObj (objv[1], &len);
1184
1185 ALL_PSYMTABS (objfile, psymtab)
1186 {
1187 if (numfiles == files_size)
1188 {
1189 files_size = files_size * 2;
1190 files = (char **) xrealloc (files, sizeof (char *) * files_size);
1191 }
1192 if (psymtab->filename)
1193 {
1194 if (!len || !strncmp(pathname, psymtab->filename,len)
1195 || !strcmp(psymtab->filename, basename(psymtab->filename)))
1196 {
1197 files[numfiles++] = basename(psymtab->filename);
1198 }
1199 }
1200 }
1201
1202 ALL_SYMTABS (objfile, symtab)
1203 {
1204 if (numfiles == files_size)
1205 {
1206 files_size = files_size * 2;
1207 files = (char **) xrealloc (files, sizeof (char *) * files_size);
1208 }
1209 if (symtab->filename && symtab->linetable && symtab->linetable->nitems)
1210 {
1211 if (!len || !strncmp(pathname, symtab->filename,len)
1212 || !strcmp(symtab->filename, basename(symtab->filename)))
1213 {
1214 files[numfiles++] = basename(symtab->filename);
1215 }
1216 }
1217 }
1218
1219 qsort (files, numfiles, sizeof(char *), comp_files);
1220
1221 lastfile = "";
1222
1223 /* Discard the old result pointer, in case it has accumulated anything
1224 and set it to a new list object */
1225
1226 Tcl_SetListObj(result_ptr->obj_ptr, 0, NULL);
1227
1228 for (i = 0; i < numfiles; i++)
1229 {
1230 if (strcmp(files[i],lastfile))
1231 Tcl_ListObjAppendElement (interp, result_ptr->obj_ptr, Tcl_NewStringObj(files[i], -1));
1232 lastfile = files[i];
1233 }
1234
1235 free (files);
1236 return TCL_OK;
1237 }
1238
1239 static int
1240 comp_files (file1, file2)
1241 const void *file1, *file2;
1242 {
1243 return strcmp(* (char **) file1, * (char **) file2);
1244 }
1245
1246
1247 /* This implements the tcl command "gdb_search"
1248 *
1249 *
1250 * Tcl Arguments:
1251 * option - One of "functions", "variables" or "types"
1252 * regexp - The regular expression to look for.
1253 * Then, optionally:
1254 * -files fileList
1255 * -static 1/0
1256 * Tcl Result:
1257 *
1258 */
1259
1260 static int
1261 gdb_search (clientData, interp, objc, objv)
1262 ClientData clientData;
1263 Tcl_Interp *interp;
1264 int objc;
1265 Tcl_Obj *CONST objv[];
1266 {
1267 struct symbol_search *ss = NULL;
1268 struct symbol_search *p;
1269 struct cleanup *old_chain = NULL;
1270 Tcl_Obj *CONST *switch_objv;
1271 int index, switch_objc, i;
1272 namespace_enum space = 0;
1273 char *regexp;
1274 int static_only, nfiles;
1275 Tcl_Obj **file_list;
1276 char **files;
1277 static char *search_options[] = { "functions", "variables", "types", (char *) NULL };
1278 static char *switches[] = { "-files", "-static", (char *) NULL };
1279 enum search_opts { SEARCH_FUNCTIONS, SEARCH_VARIABLES, SEARCH_TYPES };
1280 enum switches_opts { SWITCH_FILES, SWITCH_STATIC_ONLY };
1281
1282 if (objc < 3)
1283 {
1284 Tcl_WrongNumArgs (interp, 1, objv, "option regexp ?arg ...?");
1285 result_ptr->flags |= GDBTK_IN_TCL_RESULT;
1286 return TCL_ERROR;
1287 }
1288
1289 if (Tcl_GetIndexFromObj (interp, objv[1], search_options, "option", 0,
1290 &index) != TCL_OK)
1291 {
1292 result_ptr->flags |= GDBTK_IN_TCL_RESULT;
1293 return TCL_ERROR;
1294 }
1295
1296 /* Unfortunately, we cannot teach search_symbols to search on
1297 multiple regexps, so we have to do a two-tier search for
1298 any searches which choose to narrow the playing field. */
1299 switch ((enum search_opts) index)
1300 {
1301 case SEARCH_FUNCTIONS:
1302 space = FUNCTIONS_NAMESPACE; break;
1303 case SEARCH_VARIABLES:
1304 space = VARIABLES_NAMESPACE; break;
1305 case SEARCH_TYPES:
1306 space = TYPES_NAMESPACE; break;
1307 }
1308
1309 regexp = Tcl_GetStringFromObj (objv[2], NULL);
1310 /* Process any switches that refine the search */
1311 switch_objc = objc - 3;
1312 switch_objv = objv + 3;
1313
1314 static_only = 0;
1315 nfiles = 0;
1316 files = (char **) NULL;
1317 while (switch_objc > 0)
1318 {
1319 if (Tcl_GetIndexFromObj (interp, switch_objv[0], switches,
1320 "option", 0, &index) != TCL_OK)
1321 {
1322 result_ptr->flags |= GDBTK_IN_TCL_RESULT;
1323 return TCL_ERROR;
1324 }
1325
1326 switch ((enum switches_opts) index)
1327 {
1328 case SWITCH_FILES:
1329 {
1330 int result;
1331 if (switch_objc < 2)
1332 {
1333 Tcl_WrongNumArgs (interp, 2, objv, "[-files fileList -static 1|0]");
1334 result_ptr->flags |= GDBTK_IN_TCL_RESULT;
1335 return TCL_ERROR;
1336 }
1337 result = Tcl_ListObjGetElements (interp, switch_objv[1], &nfiles, &file_list);
1338 if (result != TCL_OK)
1339 return result;
1340
1341 files = (char **) xmalloc (nfiles * sizeof (char *));
1342 for (i = 0; i < nfiles; i++)
1343 files[i] = Tcl_GetStringFromObj (file_list[i], NULL);
1344 switch_objc--;
1345 switch_objv++;
1346 }
1347 break;
1348 case SWITCH_STATIC_ONLY:
1349 if (switch_objc < 2)
1350 {
1351 Tcl_WrongNumArgs (interp, 2, objv, "[-files fileList] [-static 1|0]");
1352 result_ptr->flags |= GDBTK_IN_TCL_RESULT;
1353 return TCL_ERROR;
1354 }
1355 if ( Tcl_GetBooleanFromObj (interp, switch_objv[1], &static_only) !=
1356 TCL_OK) {
1357 result_ptr->flags |= GDBTK_IN_TCL_RESULT;
1358 return TCL_ERROR;
1359 }
1360 switch_objc--;
1361 switch_objv++;
1362 }
1363 switch_objc--;
1364 switch_objv++;
1365 }
1366
1367 search_symbols (regexp, space, nfiles, files, &ss);
1368 if (ss != NULL)
1369 old_chain = make_cleanup (free_search_symbols, ss);
1370
1371 Tcl_SetListObj(result_ptr->obj_ptr, 0, NULL);
1372
1373 for (p = ss; p != NULL; p = p->next)
1374 {
1375 Tcl_Obj *elem;
1376
1377 if (static_only && p->block != STATIC_BLOCK)
1378 continue;
1379
1380 elem = Tcl_NewListObj (0, NULL);
1381
1382 if (p->msymbol == NULL)
1383 Tcl_ListObjAppendElement (interp, elem,
1384 Tcl_NewStringObj (SYMBOL_SOURCE_NAME (p->symbol), -1));
1385 else
1386 Tcl_ListObjAppendElement (interp, elem,
1387 Tcl_NewStringObj (SYMBOL_SOURCE_NAME (p->msymbol), -1));
1388
1389 Tcl_ListObjAppendElement (interp, result_ptr->obj_ptr, elem);
1390 }
1391
1392 if (ss != NULL)
1393 do_cleanups (old_chain);
1394
1395 return TCL_OK;
1396 }
1397
1398 /* This implements the tcl command gdb_listfuncs
1399 *
1400 * It lists all the functions defined in a given file
1401 *
1402 * Arguments:
1403 * file - the file to look in
1404 * Tcl Result:
1405 * A list of two element lists, the first element is
1406 * the symbol name, and the second is a boolean indicating
1407 * whether the symbol is demangled (1 for yes).
1408 */
1409
1410 static int
1411 gdb_listfuncs (clientData, interp, objc, objv)
1412 ClientData clientData;
1413 Tcl_Interp *interp;
1414 int objc;
1415 Tcl_Obj *CONST objv[];
1416 {
1417 struct symtab *symtab;
1418 struct blockvector *bv;
1419 struct block *b;
1420 struct symbol *sym;
1421 int i,j;
1422 Tcl_Obj *funcVals[2];
1423
1424 if (objc != 2)
1425 {
1426 Tcl_SetStringObj (result_ptr->obj_ptr, "wrong # args", -1);
1427 }
1428
1429 symtab = full_lookup_symtab (Tcl_GetStringFromObj (objv[1], NULL));
1430 if (!symtab)
1431 {
1432 Tcl_SetStringObj (result_ptr->obj_ptr, "No such file", -1);
1433 return TCL_ERROR;
1434 }
1435
1436 if (mangled == NULL)
1437 {
1438 mangled = Tcl_NewBooleanObj(1);
1439 not_mangled = Tcl_NewBooleanObj(0);
1440 Tcl_IncrRefCount(mangled);
1441 Tcl_IncrRefCount(not_mangled);
1442 }
1443
1444 Tcl_SetListObj (result_ptr->obj_ptr, 0, NULL);
1445
1446 bv = BLOCKVECTOR (symtab);
1447 for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
1448 {
1449 b = BLOCKVECTOR_BLOCK (bv, i);
1450 /* Skip the sort if this block is always sorted. */
1451 if (!BLOCK_SHOULD_SORT (b))
1452 sort_block_syms (b);
1453 for (j = 0; j < BLOCK_NSYMS (b); j++)
1454 {
1455 sym = BLOCK_SYM (b, j);
1456 if (SYMBOL_CLASS (sym) == LOC_BLOCK)
1457 {
1458
1459 char *name = cplus_demangle (SYMBOL_NAME(sym), 0);
1460 if (name)
1461 {
1462 /* strip out "global constructors" and "global destructors" */
1463 /* because we aren't interested in them. */
1464 if (strncmp (name, "global ", 7))
1465 {
1466 funcVals[0] = Tcl_NewStringObj(name, -1);
1467 funcVals[1] = mangled;
1468 }
1469 else
1470 continue;
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 if (Tcl_GetIntFromObj (NULL, *objv, &regnum) != TCL_OK)
1524 {
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 || !symtab->linetable)
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 while (fgets (line + 1, 980, fp))
2713 {
2714 if (ltable[ln >> 3] & (1 << (ln % 8)))
2715 {
2716 cur_cmd = &text_cmd_1;
2717 cur_prefix_len = prefix_len_1;
2718 }
2719 else
2720 {
2721 cur_cmd = &text_cmd_2;
2722 cur_prefix_len = prefix_len_2;
2723 }
2724
2725 Tcl_DStringAppendElement (cur_cmd, line);
2726 Tcl_DStringAppend (cur_cmd, " source_tag", 11);
2727
2728 Tcl_Eval(interp, Tcl_DStringValue(cur_cmd));
2729 Tcl_DStringSetLength(cur_cmd, cur_prefix_len);
2730
2731 ln++;
2732 }
2733 }
2734
2735 Tcl_DStringFree (&text_cmd_1);
2736 Tcl_DStringFree (&text_cmd_2);
2737 free (ltable);
2738 fclose (fp);
2739 return TCL_OK;
2740 }
2741 \f
2742 /*
2743 * This section contains commands for manipulation of breakpoints.
2744 */
2745
2746
2747 /* set a breakpoint by source file and line number */
2748 /* flags are as follows: */
2749 /* least significant 2 bits are disposition, rest is */
2750 /* type (normally 0).
2751
2752 enum bptype {
2753 bp_breakpoint, Normal breakpoint
2754 bp_hardware_breakpoint, Hardware assisted breakpoint
2755 }
2756
2757 Disposition of breakpoint. Ie: what to do after hitting it.
2758 enum bpdisp {
2759 del, Delete it
2760 del_at_next_stop, Delete at next stop, whether hit or not
2761 disable, Disable it
2762 donttouch Leave it alone
2763 };
2764 */
2765
2766 /* This implements the tcl command "gdb_set_bp"
2767 * It sets breakpoints, and runs the Tcl command
2768 * gdbtk_tcl_breakpoint create
2769 * to register the new breakpoint with the GUI.
2770 *
2771 * Tcl Arguments:
2772 * filename: the file in which to set the breakpoint
2773 * line: the line number for the breakpoint
2774 * type: the type of the breakpoint
2775 * Tcl Result:
2776 * The return value of the call to gdbtk_tcl_breakpoint.
2777 */
2778
2779 static int
2780 gdb_set_bp (clientData, interp, objc, objv)
2781 ClientData clientData;
2782 Tcl_Interp *interp;
2783 int objc;
2784 Tcl_Obj *CONST objv[];
2785
2786 {
2787 struct symtab_and_line sal;
2788 int line, flags, ret;
2789 struct breakpoint *b;
2790 char buf[64];
2791 Tcl_DString cmd;
2792
2793 if (objc != 4)
2794 {
2795 Tcl_WrongNumArgs(interp, 1, objv, "filename line type");
2796 return TCL_ERROR;
2797 }
2798
2799 sal.symtab = full_lookup_symtab (Tcl_GetStringFromObj( objv[1], NULL));
2800 if (sal.symtab == NULL)
2801 return TCL_ERROR;
2802
2803 if (Tcl_GetIntFromObj( interp, objv[2], &line) == TCL_ERROR)
2804 {
2805 result_ptr->flags = GDBTK_IN_TCL_RESULT;
2806 return TCL_ERROR;
2807 }
2808
2809 if (Tcl_GetIntFromObj( interp, objv[3], &flags) == TCL_ERROR)
2810 {
2811 result_ptr->flags = GDBTK_IN_TCL_RESULT;
2812 return TCL_ERROR;
2813 }
2814
2815 sal.line = line;
2816 if (!find_line_pc (sal.symtab, sal.line, &sal.pc))
2817 return TCL_ERROR;
2818
2819 sal.section = find_pc_overlay (sal.pc);
2820 b = set_raw_breakpoint (sal);
2821 set_breakpoint_count (breakpoint_count + 1);
2822 b->number = breakpoint_count;
2823 b->type = flags >> 2;
2824 b->disposition = flags & 3;
2825
2826 /* FIXME: this won't work for duplicate basenames! */
2827 sprintf (buf, "%s:%d", basename (Tcl_GetStringFromObj ( objv[1], NULL)), line);
2828 b->addr_string = strsave (buf);
2829
2830 /* now send notification command back to GUI */
2831
2832 Tcl_DStringInit (&cmd);
2833
2834 Tcl_DStringAppend (&cmd, "gdbtk_tcl_breakpoint create ", -1);
2835 sprintf (buf, "%d", b->number);
2836 Tcl_DStringAppendElement(&cmd, buf);
2837 sprintf (buf, "0x%lx", (long)sal.pc);
2838 Tcl_DStringAppendElement (&cmd, buf);
2839 Tcl_DStringAppendElement (&cmd, Tcl_GetStringFromObj (objv[2], NULL));
2840 Tcl_DStringAppendElement (&cmd, Tcl_GetStringFromObj (objv[1], NULL));
2841
2842 ret = Tcl_Eval (interp, Tcl_DStringValue (&cmd));
2843 Tcl_DStringFree (&cmd);
2844 return ret;
2845 }
2846
2847 /* This implements the tcl command gdb_get_breakpoint_info
2848 *
2849 *
2850 * Tcl Arguments:
2851 * breakpoint_number
2852 * Tcl Result:
2853 * A list with {file, function, line_number, address, type, enabled?,
2854 * disposition, ignore_count, {list_of_commands}, thread, hit_count}
2855 */
2856
2857 static int
2858 gdb_get_breakpoint_info (clientData, interp, objc, objv)
2859 ClientData clientData;
2860 Tcl_Interp *interp;
2861 int objc;
2862 Tcl_Obj *CONST objv[];
2863 {
2864 struct symtab_and_line sal;
2865 static char *bptypes[] = {"breakpoint", "hardware breakpoint", "until",
2866 "finish", "watchpoint", "hardware watchpoint",
2867 "read watchpoint", "access watchpoint",
2868 "longjmp", "longjmp resume", "step resume",
2869 "through sigtramp", "watchpoint scope",
2870 "call dummy" };
2871 static char *bpdisp[] = {"delete", "delstop", "disable", "donttouch"};
2872 struct command_line *cmd;
2873 int bpnum;
2874 struct breakpoint *b;
2875 extern struct breakpoint *breakpoint_chain;
2876 char *funcname, *fname, *filename;
2877 Tcl_Obj *new_obj;
2878
2879 if (objc != 2)
2880 {
2881 Tcl_SetStringObj (result_ptr->obj_ptr, "wrong number of args, should be \"breakpoint\"", -1);
2882 return TCL_ERROR;
2883 }
2884
2885 if ( Tcl_GetIntFromObj(NULL, objv[1], &bpnum) != TCL_OK)
2886 {
2887 result_ptr->flags = GDBTK_IN_TCL_RESULT;
2888 return TCL_ERROR;
2889 }
2890
2891 for (b = breakpoint_chain; b; b = b->next)
2892 if (b->number == bpnum)
2893 break;
2894
2895 if (!b || b->type != bp_breakpoint)
2896 {
2897 Tcl_SetStringObj (result_ptr->obj_ptr, "Breakpoint #%d does not exist", -1);
2898 return TCL_ERROR;
2899 }
2900
2901 sal = find_pc_line (b->address, 0);
2902
2903 filename = symtab_to_filename (sal.symtab);
2904 if (filename == NULL)
2905 filename = "";
2906
2907 Tcl_SetListObj (result_ptr->obj_ptr ,0 ,NULL);
2908 Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr,
2909 Tcl_NewStringObj (filename, -1));
2910
2911 find_pc_partial_function (b->address, &funcname, NULL, NULL);
2912 fname = cplus_demangle (funcname, 0);
2913 if (fname)
2914 {
2915 new_obj = Tcl_NewStringObj (fname, -1);
2916 free (fname);
2917 }
2918 else
2919 new_obj = Tcl_NewStringObj (funcname, -1);
2920
2921 Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, new_obj);
2922
2923 Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, Tcl_NewIntObj (b->line_number));
2924 sprintf_append_element_to_obj (result_ptr->obj_ptr, "0x%lx", b->address);
2925 Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr,
2926 Tcl_NewStringObj (bptypes[b->type], -1));
2927 Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, Tcl_NewBooleanObj(b->enable == enabled));
2928 Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr,
2929 Tcl_NewStringObj (bpdisp[b->disposition], -1));
2930 Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, Tcl_NewIntObj (b->ignore_count));
2931
2932 new_obj = Tcl_NewObj();
2933 for (cmd = b->commands; cmd; cmd = cmd->next)
2934 Tcl_ListObjAppendElement (NULL, new_obj,
2935 Tcl_NewStringObj (cmd->line, -1));
2936 Tcl_ListObjAppendElement(NULL, result_ptr->obj_ptr, new_obj);
2937
2938 Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr,
2939 Tcl_NewStringObj (b->cond_string, -1));
2940
2941 Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, Tcl_NewIntObj (b->thread));
2942 Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, Tcl_NewIntObj (b->hit_count));
2943
2944 return TCL_OK;
2945 }
2946
2947
2948 /* This implements the tcl command gdb_get_breakpoint_list
2949 * It builds up a list of the current breakpoints.
2950 *
2951 * Tcl Arguments:
2952 * None.
2953 * Tcl Result:
2954 * A list of breakpoint numbers.
2955 */
2956
2957 static int
2958 gdb_get_breakpoint_list (clientData, interp, objc, objv)
2959 ClientData clientData;
2960 Tcl_Interp *interp;
2961 int objc;
2962 Tcl_Obj *CONST objv[];
2963 {
2964 struct breakpoint *b;
2965 extern struct breakpoint *breakpoint_chain;
2966 Tcl_Obj *new_obj;
2967
2968 if (objc != 1)
2969 error ("wrong number of args, none are allowed");
2970
2971 for (b = breakpoint_chain; b; b = b->next)
2972 if (b->type == bp_breakpoint)
2973 {
2974 new_obj = Tcl_NewIntObj (b->number);
2975 Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, new_obj);
2976 }
2977
2978 return TCL_OK;
2979 }
2980 \f
2981 /* The functions in this section deal with stacks and backtraces. */
2982
2983 /* This implements the tcl command gdb_stack.
2984 * It builds up a list of stack frames.
2985 *
2986 * Tcl Arguments:
2987 * start - starting stack frame
2988 * count - number of frames to inspect
2989 * Tcl Result:
2990 * A list of function names
2991 */
2992
2993 static int
2994 gdb_stack (clientData, interp, objc, objv) ClientData clientData;
2995 Tcl_Interp *interp;
2996 int objc;
2997 Tcl_Obj *CONST objv[];
2998 {
2999 int start, count;
3000
3001 if (objc < 3)
3002 {
3003 Tcl_WrongNumArgs (interp, 1, objv, "start count");
3004 result_ptr->flags |= GDBTK_IN_TCL_RESULT;
3005 return TCL_ERROR;
3006 }
3007
3008 if (Tcl_GetIntFromObj (NULL, objv[1], &start))
3009 {
3010 result_ptr->flags |= GDBTK_IN_TCL_RESULT;
3011 return TCL_ERROR;
3012 }
3013 if (Tcl_GetIntFromObj (NULL, objv[2], &count))
3014 {
3015 result_ptr->flags |= GDBTK_IN_TCL_RESULT;
3016 return TCL_ERROR;
3017 }
3018
3019 Tcl_SetListObj (result_ptr->obj_ptr, 0, NULL);
3020
3021 if (target_has_stack)
3022 {
3023 struct frame_info *top;
3024 struct frame_info *fi;
3025
3026 /* Find the outermost frame */
3027 fi = get_current_frame ();
3028 while (fi != NULL)
3029 {
3030 top = fi;
3031 fi = get_prev_frame (fi);
3032 }
3033
3034 /* top now points to the top (outermost frame) of the
3035 stack, so point it to the requested start */
3036 start = -start;
3037 top = find_relative_frame (top, &start);
3038
3039 /* If start != 0, then we have asked to start outputting
3040 frames beyond the innermost stack frame */
3041 if (start == 0)
3042 {
3043 fi = top;
3044 while (fi && count--)
3045 {
3046 get_frame_name (interp, result_ptr->obj_ptr, fi);
3047 fi = get_next_frame (fi);
3048 }
3049 }
3050 }
3051
3052 return TCL_OK;
3053 }
3054
3055 /* A helper function for get_stack which adds information about
3056 * the stack frame FI to the caller's LIST.
3057 *
3058 * This is stolen from print_frame_info in stack.c.
3059 */
3060 static void
3061 get_frame_name (interp, list, fi)
3062 Tcl_Interp *interp;
3063 Tcl_Obj *list;
3064 struct frame_info *fi;
3065 {
3066 struct symtab_and_line sal;
3067 struct symbol *func = NULL;
3068 register char *funname = 0;
3069 enum language funlang = language_unknown;
3070 Tcl_Obj *objv[1];
3071
3072 if (frame_in_dummy (fi))
3073 {
3074 objv[0] = Tcl_NewStringObj ("<function called from gdb>\n", -1);
3075 Tcl_ListObjAppendElement (interp, list, objv[0]);
3076 return;
3077 }
3078 if (fi->signal_handler_caller)
3079 {
3080 objv[0] = Tcl_NewStringObj ("<signal handler called>\n", -1);
3081 Tcl_ListObjAppendElement (interp, list, objv[0]);
3082 return;
3083 }
3084
3085 sal =
3086 find_pc_line (fi->pc,
3087 fi->next != NULL
3088 && !fi->next->signal_handler_caller
3089 && !frame_in_dummy (fi->next));
3090
3091 func = find_pc_function (fi->pc);
3092 if (func)
3093 {
3094 struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc);
3095 if (msymbol != NULL
3096 && (SYMBOL_VALUE_ADDRESS (msymbol)
3097 > BLOCK_START (SYMBOL_BLOCK_VALUE (func))))
3098 {
3099 func = 0;
3100 funname = SYMBOL_NAME (msymbol);
3101 funlang = SYMBOL_LANGUAGE (msymbol);
3102 }
3103 else
3104 {
3105 funname = SYMBOL_NAME (func);
3106 funlang = SYMBOL_LANGUAGE (func);
3107 }
3108 }
3109 else
3110 {
3111 struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc);
3112 if (msymbol != NULL)
3113 {
3114 funname = SYMBOL_NAME (msymbol);
3115 funlang = SYMBOL_LANGUAGE (msymbol);
3116 }
3117 }
3118
3119 if (sal.symtab)
3120 {
3121 char *name = NULL;
3122
3123 if (funlang == language_cplus)
3124 name = cplus_demangle (funname, 0);
3125 if (name == NULL)
3126 name = funname;
3127
3128 objv[0] = Tcl_NewStringObj (name, -1);
3129 Tcl_ListObjAppendElement (interp, list, objv[0]);
3130 }
3131 else
3132 {
3133 #if 0
3134 /* we have no convenient way to deal with this yet... */
3135 if (fi->pc != sal.pc || !sal.symtab)
3136 {
3137 print_address_numeric (fi->pc, 1, gdb_stdout);
3138 printf_filtered (" in ");
3139 }
3140 printf_symbol_filtered (gdb_stdout, funname ? funname : "??", funlang,
3141 DMGL_ANSI);
3142 #endif
3143 objv[0] = Tcl_NewStringObj (funname != NULL ? funname : "??", -1);
3144 #ifdef PC_LOAD_SEGMENT
3145 /* If we couldn't print out function name but if can figure out what
3146 load segment this pc value is from, at least print out some info
3147 about its load segment. */
3148 if (!funname)
3149 {
3150 Tcl_AppendStringsToObj (objv[0], " from ", PC_LOAD_SEGMENT (fi->pc),
3151 (char *) NULL);
3152 }
3153 #endif
3154 #ifdef PC_SOLIB
3155 if (!funname)
3156 {
3157 char *lib = PC_SOLIB (fi->pc);
3158 if (lib)
3159 {
3160 Tcl_AppendStringsToObj (objv[0], " from ", lib, (char *) NULL);
3161 }
3162 }
3163 #endif
3164 Tcl_ListObjAppendElement (interp, list, objv[0]);
3165 }
3166 }
3167
3168 \f
3169 /*
3170 * This section contains a bunch of miscellaneous utility commands
3171 */
3172
3173 /* This implements the tcl command gdb_path_conv
3174 *
3175 * On Windows, it canonicalizes the pathname,
3176 * On Unix, it is a no op.
3177 *
3178 * Arguments:
3179 * path
3180 * Tcl Result:
3181 * The canonicalized path.
3182 */
3183
3184 static int
3185 gdb_path_conv (clientData, interp, objc, objv)
3186 ClientData clientData;
3187 Tcl_Interp *interp;
3188 int objc;
3189 Tcl_Obj *CONST objv[];
3190 {
3191 if (objc != 2)
3192 error ("wrong # args");
3193
3194 #ifdef WINNT
3195 {
3196 char pathname[256], *ptr;
3197
3198 cygwin32_conv_to_full_win32_path (Tcl_GetStringFromObj(objv[1], NULL), pathname);
3199 for (ptr = pathname; *ptr; ptr++)
3200 {
3201 if (*ptr == '\\')
3202 *ptr = '/';
3203 }
3204 Tcl_SetStringObj (result_ptr->obj_ptr, pathname, -1);
3205 }
3206 #else
3207 Tcl_SetStringObj (result_ptr->obj_ptr, Tcl_GetStringFromObj (objv[1], NULL), -1);
3208 #endif
3209
3210 return TCL_OK;
3211 }
3212 \f
3213 /*
3214 * This section has utility routines that are not Tcl commands.
3215 */
3216
3217 static int
3218 perror_with_name_wrapper (args)
3219 char * args;
3220 {
3221 perror_with_name (args);
3222 return 1;
3223 }
3224
3225 /* The lookup_symtab() in symtab.c doesn't work correctly */
3226 /* It will not work will full pathnames and if multiple */
3227 /* source files have the same basename, it will return */
3228 /* the first one instead of the correct one. This version */
3229 /* also always makes sure symtab->fullname is set. */
3230
3231 static struct symtab *
3232 full_lookup_symtab(file)
3233 char *file;
3234 {
3235 struct symtab *st;
3236 struct objfile *objfile;
3237 char *bfile, *fullname;
3238 struct partial_symtab *pt;
3239
3240 if (!file)
3241 return NULL;
3242
3243 /* first try a direct lookup */
3244 st = lookup_symtab (file);
3245 if (st)
3246 {
3247 if (!st->fullname)
3248 symtab_to_filename(st);
3249 return st;
3250 }
3251
3252 /* if the direct approach failed, try */
3253 /* looking up the basename and checking */
3254 /* all matches with the fullname */
3255 bfile = basename (file);
3256 ALL_SYMTABS (objfile, st)
3257 {
3258 if (!strcmp (bfile, basename(st->filename)))
3259 {
3260 if (!st->fullname)
3261 fullname = symtab_to_filename (st);
3262 else
3263 fullname = st->fullname;
3264
3265 if (!strcmp (file, fullname))
3266 return st;
3267 }
3268 }
3269
3270 /* still no luck? look at psymtabs */
3271 ALL_PSYMTABS (objfile, pt)
3272 {
3273 if (!strcmp (bfile, basename(pt->filename)))
3274 {
3275 st = PSYMTAB_TO_SYMTAB (pt);
3276 if (st)
3277 {
3278 fullname = symtab_to_filename (st);
3279 if (!strcmp (file, fullname))
3280 return st;
3281 }
3282 }
3283 }
3284 return NULL;
3285 }
This page took 0.099141 seconds and 4 git commands to generate.