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