]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/tracepoint.c
import gdb-1999-12-06 snapshot
[thirdparty/binutils-gdb.git] / gdb / tracepoint.c
1 /* Tracing functionality for remote targets in custom GDB protocol
2 Copyright 1997, 1998 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21 #include "defs.h"
22 #include "symtab.h"
23 #include "frame.h"
24 #include "gdbtypes.h"
25 #include "expression.h"
26 #include "gdbcmd.h"
27 #include "value.h"
28 #include "target.h"
29 #include "language.h"
30 #include "gdb_string.h"
31 #include "inferior.h"
32 #include "tracepoint.h"
33 #include "remote.h"
34
35 #include "ax.h"
36 #include "ax-gdb.h"
37
38 /* readline include files */
39 #include <readline/readline.h>
40 #include <readline/history.h>
41
42 /* readline defines this. */
43 #undef savestring
44
45 #ifdef HAVE_UNISTD_H
46 #include <unistd.h>
47 #endif
48
49 /* maximum length of an agent aexpression.
50 this accounts for the fact that packets are limited to 400 bytes
51 (which includes everything -- including the checksum), and assumes
52 the worst case of maximum length for each of the pieces of a
53 continuation packet.
54
55 NOTE: expressions get mem2hex'ed otherwise this would be twice as
56 large. (400 - 31)/2 == 184 */
57 #define MAX_AGENT_EXPR_LEN 184
58
59
60 extern int info_verbose;
61 extern void (*readline_begin_hook) PARAMS ((char *,...));
62 extern char *(*readline_hook) PARAMS ((char *));
63 extern void (*readline_end_hook) PARAMS ((void));
64 extern void x_command PARAMS ((char *, int));
65 extern int addressprint; /* Print machine addresses? */
66
67 /* GDB commands implemented in other modules:
68 */
69
70 extern void output_command PARAMS ((char *, int));
71 extern void registers_info PARAMS ((char *, int));
72 extern void args_info PARAMS ((char *, int));
73 extern void locals_info PARAMS ((char *, int));
74
75
76 /* If this definition isn't overridden by the header files, assume
77 that isatty and fileno exist on this system. */
78 #ifndef ISATTY
79 #define ISATTY(FP) (isatty (fileno (FP)))
80 #endif
81
82 /*
83 Tracepoint.c:
84
85 This module defines the following debugger commands:
86 trace : set a tracepoint on a function, line, or address.
87 info trace : list all debugger-defined tracepoints.
88 delete trace : delete one or more tracepoints.
89 enable trace : enable one or more tracepoints.
90 disable trace : disable one or more tracepoints.
91 actions : specify actions to be taken at a tracepoint.
92 passcount : specify a pass count for a tracepoint.
93 tstart : start a trace experiment.
94 tstop : stop a trace experiment.
95 tstatus : query the status of a trace experiment.
96 tfind : find a trace frame in the trace buffer.
97 tdump : print everything collected at the current tracepoint.
98 save-tracepoints : write tracepoint setup into a file.
99
100 This module defines the following user-visible debugger variables:
101 $trace_frame : sequence number of trace frame currently being debugged.
102 $trace_line : source line of trace frame currently being debugged.
103 $trace_file : source file of trace frame currently being debugged.
104 $tracepoint : tracepoint number of trace frame currently being debugged.
105 */
106
107
108 /* ======= Important global variables: ======= */
109
110 /* Chain of all tracepoints defined. */
111 struct tracepoint *tracepoint_chain;
112
113 /* Number of last tracepoint made. */
114 static int tracepoint_count;
115
116 /* Number of last traceframe collected. */
117 static int traceframe_number;
118
119 /* Tracepoint for last traceframe collected. */
120 static int tracepoint_number;
121
122 /* Symbol for function for last traceframe collected */
123 static struct symbol *traceframe_fun;
124
125 /* Symtab and line for last traceframe collected */
126 static struct symtab_and_line traceframe_sal;
127
128 /* Tracing command lists */
129 static struct cmd_list_element *tfindlist;
130
131 /* ======= Important command functions: ======= */
132 static void trace_command PARAMS ((char *, int));
133 static void tracepoints_info PARAMS ((char *, int));
134 static void delete_trace_command PARAMS ((char *, int));
135 static void enable_trace_command PARAMS ((char *, int));
136 static void disable_trace_command PARAMS ((char *, int));
137 static void trace_pass_command PARAMS ((char *, int));
138 static void trace_actions_command PARAMS ((char *, int));
139 static void trace_start_command PARAMS ((char *, int));
140 static void trace_stop_command PARAMS ((char *, int));
141 static void trace_status_command PARAMS ((char *, int));
142 static void trace_find_command PARAMS ((char *, int));
143 static void trace_find_pc_command PARAMS ((char *, int));
144 static void trace_find_tracepoint_command PARAMS ((char *, int));
145 static void trace_find_line_command PARAMS ((char *, int));
146 static void trace_find_range_command PARAMS ((char *, int));
147 static void trace_find_outside_command PARAMS ((char *, int));
148 static void tracepoint_save_command PARAMS ((char *, int));
149 static void trace_dump_command PARAMS ((char *, int));
150
151 /* support routines */
152 static void trace_mention PARAMS ((struct tracepoint *));
153
154 struct collection_list;
155 static void add_aexpr PARAMS ((struct collection_list *, struct agent_expr *));
156 static unsigned char *mem2hex (unsigned char *, unsigned char *, int);
157 static void add_register PARAMS ((struct collection_list * collection,
158 unsigned int regno));
159 static void free_actions_list PARAMS ((char **actions_list));
160 static void free_actions_list_cleanup_wrapper PARAMS ((void *));
161
162 extern void _initialize_tracepoint PARAMS ((void));
163
164 /* Utility: returns true if "target remote" */
165 static int
166 target_is_remote ()
167 {
168 if (current_target.to_shortname &&
169 strcmp (current_target.to_shortname, "remote") == 0)
170 return 1;
171 else
172 return 0;
173 }
174
175 /* Utility: generate error from an incoming stub packet. */
176 static void
177 trace_error (buf)
178 char *buf;
179 {
180 if (*buf++ != 'E')
181 return; /* not an error msg */
182 switch (*buf)
183 {
184 case '1': /* malformed packet error */
185 if (*++buf == '0') /* general case: */
186 error ("tracepoint.c: error in outgoing packet.");
187 else
188 error ("tracepoint.c: error in outgoing packet at field #%d.",
189 strtol (buf, NULL, 16));
190 case '2':
191 error ("trace API error 0x%s.", ++buf);
192 default:
193 error ("Target returns error code '%s'.", buf);
194 }
195 }
196
197 /* Utility: wait for reply from stub, while accepting "O" packets */
198 static char *
199 remote_get_noisy_reply (char *buf,
200 long sizeof_buf)
201 {
202 do /* loop on reply from remote stub */
203 {
204 QUIT; /* allow user to bail out with ^C */
205 getpkt (buf, sizeof_buf, 0);
206 if (buf[0] == 0)
207 error ("Target does not support this command.");
208 else if (buf[0] == 'E')
209 trace_error (buf);
210 else if (buf[0] == 'O' &&
211 buf[1] != 'K')
212 remote_console_output (buf + 1); /* 'O' message from stub */
213 else
214 return buf; /* here's the actual reply */
215 }
216 while (1);
217 }
218
219 /* Set tracepoint count to NUM. */
220 static void
221 set_tracepoint_count (num)
222 int num;
223 {
224 tracepoint_count = num;
225 set_internalvar (lookup_internalvar ("tpnum"),
226 value_from_longest (builtin_type_int, (LONGEST) num));
227 }
228
229 /* Set traceframe number to NUM. */
230 static void
231 set_traceframe_num (num)
232 int num;
233 {
234 traceframe_number = num;
235 set_internalvar (lookup_internalvar ("trace_frame"),
236 value_from_longest (builtin_type_int, (LONGEST) num));
237 }
238
239 /* Set tracepoint number to NUM. */
240 static void
241 set_tracepoint_num (num)
242 int num;
243 {
244 tracepoint_number = num;
245 set_internalvar (lookup_internalvar ("tracepoint"),
246 value_from_longest (builtin_type_int, (LONGEST) num));
247 }
248
249 /* Set externally visible debug variables for querying/printing
250 the traceframe context (line, function, file) */
251
252 static void
253 set_traceframe_context (trace_pc)
254 CORE_ADDR trace_pc;
255 {
256 static struct type *func_string, *file_string;
257 static struct type *func_range, *file_range;
258 static value_ptr func_val, file_val;
259 static struct type *charstar;
260 int len;
261
262 if (charstar == (struct type *) NULL)
263 charstar = lookup_pointer_type (builtin_type_char);
264
265 if (trace_pc == -1) /* cease debugging any trace buffers */
266 {
267 traceframe_fun = 0;
268 traceframe_sal.pc = traceframe_sal.line = 0;
269 traceframe_sal.symtab = NULL;
270 set_internalvar (lookup_internalvar ("trace_func"),
271 value_from_longest (charstar, (LONGEST) 0));
272 set_internalvar (lookup_internalvar ("trace_file"),
273 value_from_longest (charstar, (LONGEST) 0));
274 set_internalvar (lookup_internalvar ("trace_line"),
275 value_from_longest (builtin_type_int, (LONGEST) - 1));
276 return;
277 }
278
279 /* save as globals for internal use */
280 traceframe_sal = find_pc_line (trace_pc, 0);
281 traceframe_fun = find_pc_function (trace_pc);
282
283 /* save linenumber as "$trace_line", a debugger variable visible to users */
284 set_internalvar (lookup_internalvar ("trace_line"),
285 value_from_longest (builtin_type_int,
286 (LONGEST) traceframe_sal.line));
287
288 /* save func name as "$trace_func", a debugger variable visible to users */
289 if (traceframe_fun == NULL ||
290 SYMBOL_NAME (traceframe_fun) == NULL)
291 set_internalvar (lookup_internalvar ("trace_func"),
292 value_from_longest (charstar, (LONGEST) 0));
293 else
294 {
295 len = strlen (SYMBOL_NAME (traceframe_fun));
296 func_range = create_range_type (func_range,
297 builtin_type_int, 0, len - 1);
298 func_string = create_array_type (func_string,
299 builtin_type_char, func_range);
300 func_val = allocate_value (func_string);
301 VALUE_TYPE (func_val) = func_string;
302 memcpy (VALUE_CONTENTS_RAW (func_val),
303 SYMBOL_NAME (traceframe_fun),
304 len);
305 func_val->modifiable = 0;
306 set_internalvar (lookup_internalvar ("trace_func"), func_val);
307 }
308
309 /* save file name as "$trace_file", a debugger variable visible to users */
310 if (traceframe_sal.symtab == NULL ||
311 traceframe_sal.symtab->filename == NULL)
312 set_internalvar (lookup_internalvar ("trace_file"),
313 value_from_longest (charstar, (LONGEST) 0));
314 else
315 {
316 len = strlen (traceframe_sal.symtab->filename);
317 file_range = create_range_type (file_range,
318 builtin_type_int, 0, len - 1);
319 file_string = create_array_type (file_string,
320 builtin_type_char, file_range);
321 file_val = allocate_value (file_string);
322 VALUE_TYPE (file_val) = file_string;
323 memcpy (VALUE_CONTENTS_RAW (file_val),
324 traceframe_sal.symtab->filename,
325 len);
326 file_val->modifiable = 0;
327 set_internalvar (lookup_internalvar ("trace_file"), file_val);
328 }
329 }
330
331 /* Low level routine to set a tracepoint.
332 Returns the tracepoint object so caller can set other things.
333 Does not set the tracepoint number!
334 Does not print anything.
335
336 ==> This routine should not be called if there is a chance of later
337 error(); otherwise it leaves a bogus tracepoint on the chain. Validate
338 your arguments BEFORE calling this routine! */
339
340 static struct tracepoint *
341 set_raw_tracepoint (sal)
342 struct symtab_and_line sal;
343 {
344 register struct tracepoint *t, *tc;
345 struct cleanup *old_chain;
346
347 t = (struct tracepoint *) xmalloc (sizeof (struct tracepoint));
348 old_chain = make_cleanup (free, t);
349 memset (t, 0, sizeof (*t));
350 t->address = sal.pc;
351 if (sal.symtab == NULL)
352 t->source_file = NULL;
353 else
354 t->source_file = savestring (sal.symtab->filename,
355 strlen (sal.symtab->filename));
356
357 t->section = sal.section;
358 t->language = current_language->la_language;
359 t->input_radix = input_radix;
360 t->line_number = sal.line;
361 t->enabled = enabled;
362 t->next = 0;
363 t->step_count = 0;
364 t->pass_count = 0;
365 t->addr_string = NULL;
366
367 /* Add this tracepoint to the end of the chain
368 so that a list of tracepoints will come out in order
369 of increasing numbers. */
370
371 tc = tracepoint_chain;
372 if (tc == 0)
373 tracepoint_chain = t;
374 else
375 {
376 while (tc->next)
377 tc = tc->next;
378 tc->next = t;
379 }
380 discard_cleanups (old_chain);
381 return t;
382 }
383
384 /* Set a tracepoint according to ARG (function, linenum or *address) */
385 static void
386 trace_command (arg, from_tty)
387 char *arg;
388 int from_tty;
389 {
390 char **canonical = (char **) NULL;
391 struct symtabs_and_lines sals;
392 struct symtab_and_line sal;
393 struct tracepoint *t;
394 char *addr_start = 0, *addr_end = 0;
395 int i;
396
397 if (!arg || !*arg)
398 error ("trace command requires an argument");
399
400 if (from_tty && info_verbose)
401 printf_filtered ("TRACE %s\n", arg);
402
403 addr_start = arg;
404 sals = decode_line_1 (&arg, 1, (struct symtab *) NULL, 0, &canonical);
405 addr_end = arg;
406 if (!sals.nelts)
407 return; /* ??? Presumably decode_line_1 has already warned? */
408
409 /* Resolve all line numbers to PC's */
410 for (i = 0; i < sals.nelts; i++)
411 resolve_sal_pc (&sals.sals[i]);
412
413 /* Now set all the tracepoints. */
414 for (i = 0; i < sals.nelts; i++)
415 {
416 sal = sals.sals[i];
417
418 t = set_raw_tracepoint (sal);
419 set_tracepoint_count (tracepoint_count + 1);
420 t->number = tracepoint_count;
421
422 /* If a canonical line spec is needed use that instead of the
423 command string. */
424 if (canonical != (char **) NULL && canonical[i] != NULL)
425 t->addr_string = canonical[i];
426 else if (addr_start)
427 t->addr_string = savestring (addr_start, addr_end - addr_start);
428
429 trace_mention (t);
430
431 /* Let the UI know of any additions */
432 if (create_tracepoint_hook)
433 create_tracepoint_hook (t);
434 }
435
436 if (sals.nelts > 1)
437 {
438 printf_filtered ("Multiple tracepoints were set.\n");
439 printf_filtered ("Use 'delete trace' to delete unwanted tracepoints.\n");
440 }
441 }
442
443 /* Tell the user we have just set a tracepoint TP. */
444
445 static void
446 trace_mention (tp)
447 struct tracepoint *tp;
448 {
449 printf_filtered ("Tracepoint %d", tp->number);
450
451 if (addressprint || (tp->source_file == NULL))
452 {
453 printf_filtered (" at ");
454 print_address_numeric (tp->address, 1, gdb_stdout);
455 }
456 if (tp->source_file)
457 printf_filtered (": file %s, line %d.",
458 tp->source_file, tp->line_number);
459
460 printf_filtered ("\n");
461 }
462
463 /* Print information on tracepoint number TPNUM_EXP, or all if omitted. */
464
465 static void
466 tracepoints_info (tpnum_exp, from_tty)
467 char *tpnum_exp;
468 int from_tty;
469 {
470 struct tracepoint *t;
471 struct action_line *action;
472 int found_a_tracepoint = 0;
473 char wrap_indent[80];
474 struct symbol *sym;
475 int tpnum = -1;
476
477 if (tpnum_exp)
478 tpnum = parse_and_eval_address (tpnum_exp);
479
480 ALL_TRACEPOINTS (t)
481 if (tpnum == -1 || tpnum == t->number)
482 {
483 extern int addressprint; /* print machine addresses? */
484
485 if (!found_a_tracepoint++)
486 {
487 printf_filtered ("Num Enb ");
488 if (addressprint)
489 printf_filtered ("Address ");
490 printf_filtered ("PassC StepC What\n");
491 }
492 strcpy (wrap_indent, " ");
493 if (addressprint)
494 strcat (wrap_indent, " ");
495
496 printf_filtered ("%-3d %-3s ", t->number,
497 t->enabled == enabled ? "y" : "n");
498 if (addressprint)
499 printf_filtered ("%s ",
500 local_hex_string_custom ((unsigned long) t->address,
501 "08l"));
502 printf_filtered ("%-5d %-5d ", t->pass_count, t->step_count);
503
504 if (t->source_file)
505 {
506 sym = find_pc_sect_function (t->address, t->section);
507 if (sym)
508 {
509 fputs_filtered ("in ", gdb_stdout);
510 fputs_filtered (SYMBOL_SOURCE_NAME (sym), gdb_stdout);
511 wrap_here (wrap_indent);
512 fputs_filtered (" at ", gdb_stdout);
513 }
514 fputs_filtered (t->source_file, gdb_stdout);
515 printf_filtered (":%d", t->line_number);
516 }
517 else
518 print_address_symbolic (t->address, gdb_stdout, demangle, " ");
519
520 printf_filtered ("\n");
521 if (t->actions)
522 {
523 printf_filtered (" Actions for tracepoint %d: \n", t->number);
524 for (action = t->actions; action; action = action->next)
525 {
526 printf_filtered ("\t%s\n", action->action);
527 }
528 }
529 }
530 if (!found_a_tracepoint)
531 {
532 if (tpnum == -1)
533 printf_filtered ("No tracepoints.\n");
534 else
535 printf_filtered ("No tracepoint number %d.\n", tpnum);
536 }
537 }
538
539 /* Optimization: the code to parse an enable, disable, or delete TP command
540 is virtually identical except for whether it performs an enable, disable,
541 or delete. Therefore I've combined them into one function with an opcode.
542 */
543 enum tracepoint_opcode
544 {
545 enable_op,
546 disable_op,
547 delete_op
548 };
549
550 /* This function implements enable, disable and delete commands. */
551 static void
552 tracepoint_operation (t, from_tty, opcode)
553 struct tracepoint *t;
554 int from_tty;
555 enum tracepoint_opcode opcode;
556 {
557 struct tracepoint *t2;
558
559 if (t == NULL) /* no tracepoint operand */
560 return;
561
562 switch (opcode)
563 {
564 case enable_op:
565 t->enabled = enabled;
566 if (modify_tracepoint_hook)
567 modify_tracepoint_hook (t);
568 break;
569 case disable_op:
570 t->enabled = disabled;
571 if (modify_tracepoint_hook)
572 modify_tracepoint_hook (t);
573 break;
574 case delete_op:
575 if (tracepoint_chain == t)
576 tracepoint_chain = t->next;
577
578 ALL_TRACEPOINTS (t2)
579 if (t2->next == t)
580 {
581 t2->next = t->next;
582 break;
583 }
584
585 /* Let the UI know of any deletions */
586 if (delete_tracepoint_hook)
587 delete_tracepoint_hook (t);
588
589 if (t->addr_string)
590 free (t->addr_string);
591 if (t->source_file)
592 free (t->source_file);
593 if (t->actions)
594 free_actions (t);
595
596 free (t);
597 break;
598 }
599 }
600
601 /* Utility: parse a tracepoint number and look it up in the list.
602 If MULTI_P is true, there might be a range of tracepoints in ARG.
603 if OPTIONAL_P is true, then if the argument is missing, the most
604 recent tracepoint (tracepoint_count) is returned. */
605 struct tracepoint *
606 get_tracepoint_by_number (arg, multi_p, optional_p)
607 char **arg;
608 int multi_p, optional_p;
609 {
610 struct tracepoint *t;
611 int tpnum;
612 char *instring = arg == NULL ? NULL : *arg;
613
614 if (arg == NULL || *arg == NULL || ! **arg)
615 {
616 if (optional_p)
617 tpnum = tracepoint_count;
618 else
619 error_no_arg ("tracepoint number");
620 }
621 else
622 tpnum = multi_p ? get_number_or_range (arg) : get_number (arg);
623
624 if (tpnum <= 0)
625 {
626 if (instring && *instring)
627 printf_filtered ("bad tracepoint number at or near '%s'\n", instring);
628 else
629 printf_filtered ("Tracepoint argument missing and no previous tracepoint\n");
630 return NULL;
631 }
632
633 ALL_TRACEPOINTS (t)
634 if (t->number == tpnum)
635 {
636 return t;
637 }
638
639 /* FIXME: if we are in the middle of a range we don't want to give
640 a message. The current interface to get_number_or_range doesn't
641 allow us to discover this. */
642 printf_unfiltered ("No tracepoint number %d.\n", tpnum);
643 return NULL;
644 }
645
646 /* Utility: parse a list of tracepoint numbers, and call a func for each. */
647 static void
648 map_args_over_tracepoints (args, from_tty, opcode)
649 char *args;
650 int from_tty;
651 enum tracepoint_opcode opcode;
652 {
653 struct tracepoint *t, *tmp;
654
655 if (args == 0 || *args == 0) /* do them all */
656 ALL_TRACEPOINTS_SAFE (t, tmp)
657 tracepoint_operation (t, from_tty, opcode);
658 else
659 while (*args)
660 {
661 QUIT; /* give user option to bail out with ^C */
662 t = get_tracepoint_by_number (&args, 1, 0);
663 tracepoint_operation (t, from_tty, opcode);
664 while (*args == ' ' || *args == '\t')
665 args++;
666 }
667 }
668
669 /* The 'enable trace' command enables tracepoints. Not supported by all targets. */
670 static void
671 enable_trace_command (args, from_tty)
672 char *args;
673 int from_tty;
674 {
675 dont_repeat ();
676 map_args_over_tracepoints (args, from_tty, enable_op);
677 }
678
679 /* The 'disable trace' command enables tracepoints. Not supported by all targets. */
680 static void
681 disable_trace_command (args, from_tty)
682 char *args;
683 int from_tty;
684 {
685 dont_repeat ();
686 map_args_over_tracepoints (args, from_tty, disable_op);
687 }
688
689 /* Remove a tracepoint (or all if no argument) */
690 static void
691 delete_trace_command (args, from_tty)
692 char *args;
693 int from_tty;
694 {
695 dont_repeat ();
696 if (!args || !*args) /* No args implies all tracepoints; */
697 if (from_tty) /* confirm only if from_tty... */
698 if (tracepoint_chain) /* and if there are tracepoints to delete! */
699 if (!query ("Delete all tracepoints? "))
700 return;
701
702 map_args_over_tracepoints (args, from_tty, delete_op);
703 }
704
705 /* Set passcount for tracepoint.
706
707 First command argument is passcount, second is tracepoint number.
708 If tracepoint number omitted, apply to most recently defined.
709 Also accepts special argument "all". */
710
711 static void
712 trace_pass_command (args, from_tty)
713 char *args;
714 int from_tty;
715 {
716 struct tracepoint *t1 = (struct tracepoint *) -1, *t2;
717 unsigned int count;
718 int all = 0;
719
720 if (args == 0 || *args == 0)
721 error ("passcount command requires an argument (count + optional TP num)");
722
723 count = strtoul (args, &args, 10); /* count comes first, then TP num */
724
725 while (*args && isspace ((int) *args))
726 args++;
727
728 if (*args && strncasecmp (args, "all", 3) == 0)
729 {
730 args += 3; /* skip special argument "all" */
731 all = 1;
732 if (*args)
733 error ("Junk at end of arguments.");
734 }
735 else
736 t1 = get_tracepoint_by_number (&args, 1, 1);
737
738 do
739 {
740 if (t1)
741 {
742 ALL_TRACEPOINTS (t2)
743 if (t1 == (struct tracepoint *) -1 || t1 == t2)
744 {
745 t2->pass_count = count;
746 if (modify_tracepoint_hook)
747 modify_tracepoint_hook (t2);
748 if (from_tty)
749 printf_filtered ("Setting tracepoint %d's passcount to %d\n",
750 t2->number, count);
751 }
752 if (! all && *args)
753 t1 = get_tracepoint_by_number (&args, 1, 0);
754 }
755 }
756 while (*args);
757 }
758
759 /* ACTIONS functions: */
760
761 /* Prototypes for action-parsing utility commands */
762 static void read_actions PARAMS ((struct tracepoint *));
763
764 /* The three functions:
765 collect_pseudocommand,
766 while_stepping_pseudocommand, and
767 end_actions_pseudocommand
768 are placeholders for "commands" that are actually ONLY to be used
769 within a tracepoint action list. If the actual function is ever called,
770 it means that somebody issued the "command" at the top level,
771 which is always an error. */
772
773 static void
774 end_actions_pseudocommand (args, from_tty)
775 char *args;
776 int from_tty;
777 {
778 error ("This command cannot be used at the top level.");
779 }
780
781 static void
782 while_stepping_pseudocommand (args, from_tty)
783 char *args;
784 int from_tty;
785 {
786 error ("This command can only be used in a tracepoint actions list.");
787 }
788
789 static void
790 collect_pseudocommand (args, from_tty)
791 char *args;
792 int from_tty;
793 {
794 error ("This command can only be used in a tracepoint actions list.");
795 }
796
797 /* Enter a list of actions for a tracepoint. */
798 static void
799 trace_actions_command (args, from_tty)
800 char *args;
801 int from_tty;
802 {
803 struct tracepoint *t;
804 char tmpbuf[128];
805 char *end_msg = "End with a line saying just \"end\".";
806
807 t = get_tracepoint_by_number (&args, 0, 1);
808 if (t)
809 {
810 sprintf (tmpbuf, "Enter actions for tracepoint %d, one per line.",
811 t->number);
812
813 if (from_tty)
814 {
815 if (readline_begin_hook)
816 (*readline_begin_hook) ("%s %s\n", tmpbuf, end_msg);
817 else if (input_from_terminal_p ())
818 printf_filtered ("%s\n%s\n", tmpbuf, end_msg);
819 }
820
821 free_actions (t);
822 t->step_count = 0; /* read_actions may set this */
823 read_actions (t);
824
825 if (readline_end_hook)
826 (*readline_end_hook) ();
827 /* tracepoints_changed () */
828 }
829 /* else just return */
830 }
831
832 /* worker function */
833 static void
834 read_actions (t)
835 struct tracepoint *t;
836 {
837 char *line;
838 char *prompt1 = "> ", *prompt2 = " > ";
839 char *prompt = prompt1;
840 enum actionline_type linetype;
841 extern FILE *instream;
842 struct action_line *next = NULL, *temp;
843 struct cleanup *old_chain;
844
845 /* Control-C quits instantly if typed while in this loop
846 since it should not wait until the user types a newline. */
847 immediate_quit++;
848 #ifdef STOP_SIGNAL
849 if (job_control)
850 {
851 if (event_loop_p)
852 signal (STOP_SIGNAL, handle_stop_sig);
853 else
854 signal (STOP_SIGNAL, stop_sig);
855 }
856 #endif
857 old_chain = make_cleanup ((make_cleanup_func) free_actions, (void *) t);
858 while (1)
859 {
860 /* Make sure that all output has been output. Some machines may let
861 you get away with leaving out some of the gdb_flush, but not all. */
862 wrap_here ("");
863 gdb_flush (gdb_stdout);
864 gdb_flush (gdb_stderr);
865
866 if (readline_hook && instream == NULL)
867 line = (*readline_hook) (prompt);
868 else if (instream == stdin && ISATTY (instream))
869 {
870 line = readline (prompt);
871 if (line && *line) /* add it to command history */
872 add_history (line);
873 }
874 else
875 line = gdb_readline (0);
876
877 linetype = validate_actionline (&line, t);
878 if (linetype == BADLINE)
879 continue; /* already warned -- collect another line */
880
881 temp = xmalloc (sizeof (struct action_line));
882 temp->next = NULL;
883 temp->action = line;
884
885 if (next == NULL) /* first action for this tracepoint? */
886 t->actions = next = temp;
887 else
888 {
889 next->next = temp;
890 next = temp;
891 }
892
893 if (linetype == STEPPING) /* begin "while-stepping" */
894 {
895 if (prompt == prompt2)
896 {
897 warning ("Already processing 'while-stepping'");
898 continue;
899 }
900 else
901 prompt = prompt2; /* change prompt for stepping actions */
902 }
903 else if (linetype == END)
904 {
905 if (prompt == prompt2)
906 {
907 prompt = prompt1; /* end of single-stepping actions */
908 }
909 else
910 { /* end of actions */
911 if (t->actions->next == NULL)
912 {
913 /* an "end" all by itself with no other actions means
914 this tracepoint has no actions. Discard empty list. */
915 free_actions (t);
916 }
917 break;
918 }
919 }
920 }
921 #ifdef STOP_SIGNAL
922 if (job_control)
923 signal (STOP_SIGNAL, SIG_DFL);
924 #endif
925 immediate_quit = 0;
926 discard_cleanups (old_chain);
927 }
928
929 /* worker function */
930 enum actionline_type
931 validate_actionline (line, t)
932 char **line;
933 struct tracepoint *t;
934 {
935 struct cmd_list_element *c;
936 struct expression *exp = NULL;
937 struct cleanup *old_chain = NULL;
938 char *p;
939
940 for (p = *line; isspace ((int) *p);)
941 p++;
942
943 /* symbol lookup etc. */
944 if (*p == '\0') /* empty line: just prompt for another line. */
945 return BADLINE;
946
947 if (*p == '#') /* comment line */
948 return GENERIC;
949
950 c = lookup_cmd (&p, cmdlist, "", -1, 1);
951 if (c == 0)
952 {
953 warning ("'%s' is not an action that I know, or is ambiguous.", p);
954 return BADLINE;
955 }
956
957 if (c->function.cfunc == collect_pseudocommand)
958 {
959 struct agent_expr *aexpr;
960 struct agent_reqs areqs;
961
962 do
963 { /* repeat over a comma-separated list */
964 QUIT; /* allow user to bail out with ^C */
965 while (isspace ((int) *p))
966 p++;
967
968 if (*p == '$') /* look for special pseudo-symbols */
969 {
970 if ((0 == strncasecmp ("reg", p + 1, 3)) ||
971 (0 == strncasecmp ("arg", p + 1, 3)) ||
972 (0 == strncasecmp ("loc", p + 1, 3)))
973 {
974 p = strchr (p, ',');
975 continue;
976 }
977 /* else fall thru, treat p as an expression and parse it! */
978 }
979 exp = parse_exp_1 (&p, block_for_pc (t->address), 1);
980 old_chain = make_cleanup ((make_cleanup_func) free_current_contents,
981 &exp);
982
983 if (exp->elts[0].opcode == OP_VAR_VALUE)
984 {
985 if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_CONST)
986 {
987 warning ("constant %s (value %ld) will not be collected.",
988 SYMBOL_NAME (exp->elts[2].symbol),
989 SYMBOL_VALUE (exp->elts[2].symbol));
990 return BADLINE;
991 }
992 else if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_OPTIMIZED_OUT)
993 {
994 warning ("%s is optimized away and cannot be collected.",
995 SYMBOL_NAME (exp->elts[2].symbol));
996 return BADLINE;
997 }
998 }
999
1000 /* we have something to collect, make sure that the expr to
1001 bytecode translator can handle it and that it's not too long */
1002 aexpr = gen_trace_for_expr (t->address, exp);
1003 (void) make_cleanup ((make_cleanup_func) free_agent_expr, aexpr);
1004
1005 if (aexpr->len > MAX_AGENT_EXPR_LEN)
1006 error ("expression too complicated, try simplifying");
1007
1008 ax_reqs (aexpr, &areqs);
1009 (void) make_cleanup (free, areqs.reg_mask);
1010
1011 if (areqs.flaw != agent_flaw_none)
1012 error ("malformed expression");
1013
1014 if (areqs.min_height < 0)
1015 error ("gdb: Internal error: expression has min height < 0");
1016
1017 if (areqs.max_height > 20)
1018 error ("expression too complicated, try simplifying");
1019
1020 do_cleanups (old_chain);
1021 }
1022 while (p && *p++ == ',');
1023 return GENERIC;
1024 }
1025 else if (c->function.cfunc == while_stepping_pseudocommand)
1026 {
1027 char *steparg; /* in case warning is necessary */
1028
1029 while (isspace ((int) *p))
1030 p++;
1031 steparg = p;
1032
1033 if (*p == '\0' ||
1034 (t->step_count = strtol (p, &p, 0)) == 0)
1035 {
1036 warning ("'%s': bad step-count; command ignored.", *line);
1037 return BADLINE;
1038 }
1039 return STEPPING;
1040 }
1041 else if (c->function.cfunc == end_actions_pseudocommand)
1042 return END;
1043 else
1044 {
1045 warning ("'%s' is not a supported tracepoint action.", *line);
1046 return BADLINE;
1047 }
1048 }
1049
1050 /* worker function */
1051 void
1052 free_actions (t)
1053 struct tracepoint *t;
1054 {
1055 struct action_line *line, *next;
1056
1057 for (line = t->actions; line; line = next)
1058 {
1059 next = line->next;
1060 if (line->action)
1061 free (line->action);
1062 free (line);
1063 }
1064 t->actions = NULL;
1065 }
1066
1067 struct memrange
1068 {
1069 int type; /* 0 for absolute memory range, else basereg number */
1070 bfd_signed_vma start;
1071 bfd_signed_vma end;
1072 };
1073
1074 struct collection_list
1075 {
1076 unsigned char regs_mask[8]; /* room for up to 256 regs */
1077 long listsize;
1078 long next_memrange;
1079 struct memrange *list;
1080 long aexpr_listsize; /* size of array pointed to by expr_list elt */
1081 long next_aexpr_elt;
1082 struct agent_expr **aexpr_list;
1083
1084 }
1085 tracepoint_list, stepping_list;
1086
1087 /* MEMRANGE functions: */
1088
1089 static int memrange_cmp PARAMS ((const void *, const void *));
1090
1091 /* compare memranges for qsort */
1092 static int
1093 memrange_cmp (va, vb)
1094 const void *va;
1095 const void *vb;
1096 {
1097 const struct memrange *a = va, *b = vb;
1098
1099 if (a->type < b->type)
1100 return -1;
1101 if (a->type > b->type)
1102 return 1;
1103 if (a->type == 0)
1104 {
1105 if ((bfd_vma) a->start < (bfd_vma) b->start)
1106 return -1;
1107 if ((bfd_vma) a->start > (bfd_vma) b->start)
1108 return 1;
1109 }
1110 else
1111 {
1112 if (a->start < b->start)
1113 return -1;
1114 if (a->start > b->start)
1115 return 1;
1116 }
1117 return 0;
1118 }
1119
1120 /* Sort the memrange list using qsort, and merge adjacent memranges */
1121 static void
1122 memrange_sortmerge (memranges)
1123 struct collection_list *memranges;
1124 {
1125 int a, b;
1126
1127 qsort (memranges->list, memranges->next_memrange,
1128 sizeof (struct memrange), memrange_cmp);
1129 if (memranges->next_memrange > 0)
1130 {
1131 for (a = 0, b = 1; b < memranges->next_memrange; b++)
1132 {
1133 if (memranges->list[a].type == memranges->list[b].type &&
1134 memranges->list[b].start - memranges->list[a].end <=
1135 MAX_REGISTER_VIRTUAL_SIZE)
1136 {
1137 /* memrange b starts before memrange a ends; merge them. */
1138 if (memranges->list[b].end > memranges->list[a].end)
1139 memranges->list[a].end = memranges->list[b].end;
1140 continue; /* next b, same a */
1141 }
1142 a++; /* next a */
1143 if (a != b)
1144 memcpy (&memranges->list[a], &memranges->list[b],
1145 sizeof (struct memrange));
1146 }
1147 memranges->next_memrange = a + 1;
1148 }
1149 }
1150
1151 /* Add a register to a collection list */
1152 static void
1153 add_register (collection, regno)
1154 struct collection_list *collection;
1155 unsigned int regno;
1156 {
1157 if (info_verbose)
1158 printf_filtered ("collect register %d\n", regno);
1159 if (regno > (8 * sizeof (collection->regs_mask)))
1160 error ("Internal: register number %d too large for tracepoint",
1161 regno);
1162 collection->regs_mask[regno / 8] |= 1 << (regno % 8);
1163 }
1164
1165 /* Add a memrange to a collection list */
1166 static void
1167 add_memrange (memranges, type, base, len)
1168 struct collection_list *memranges;
1169 int type;
1170 bfd_signed_vma base;
1171 unsigned long len;
1172 {
1173 if (info_verbose)
1174 {
1175 printf_filtered ("(%d,", type);
1176 printf_vma (base);
1177 printf_filtered (",%ld)\n", len);
1178 }
1179
1180 /* type: 0 == memory, n == basereg */
1181 memranges->list[memranges->next_memrange].type = type;
1182 /* base: addr if memory, offset if reg relative. */
1183 memranges->list[memranges->next_memrange].start = base;
1184 /* len: we actually save end (base + len) for convenience */
1185 memranges->list[memranges->next_memrange].end = base + len;
1186 memranges->next_memrange++;
1187 if (memranges->next_memrange >= memranges->listsize)
1188 {
1189 memranges->listsize *= 2;
1190 memranges->list = xrealloc (memranges->list,
1191 memranges->listsize);
1192 }
1193
1194 if (type != -1) /* better collect the base register! */
1195 add_register (memranges, type);
1196 }
1197
1198 /* Add a symbol to a collection list */
1199 static void
1200 collect_symbol (collect, sym, frame_regno, frame_offset)
1201 struct collection_list *collect;
1202 struct symbol *sym;
1203 long frame_regno;
1204 long frame_offset;
1205 {
1206 unsigned long len;
1207 unsigned int reg;
1208 bfd_signed_vma offset;
1209
1210 len = TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym)));
1211 switch (SYMBOL_CLASS (sym))
1212 {
1213 default:
1214 printf_filtered ("%s: don't know symbol class %d\n",
1215 SYMBOL_NAME (sym), SYMBOL_CLASS (sym));
1216 break;
1217 case LOC_CONST:
1218 printf_filtered ("constant %s (value %ld) will not be collected.\n",
1219 SYMBOL_NAME (sym), SYMBOL_VALUE (sym));
1220 break;
1221 case LOC_STATIC:
1222 offset = SYMBOL_VALUE_ADDRESS (sym);
1223 if (info_verbose)
1224 {
1225 char tmp[40];
1226
1227 sprintf_vma (tmp, offset);
1228 printf_filtered ("LOC_STATIC %s: collect %ld bytes at %s.\n",
1229 SYMBOL_NAME (sym), len, tmp /* address */);
1230 }
1231 add_memrange (collect, -1, offset, len); /* 0 == memory */
1232 break;
1233 case LOC_REGISTER:
1234 case LOC_REGPARM:
1235 reg = SYMBOL_VALUE (sym);
1236 if (info_verbose)
1237 printf_filtered ("LOC_REG[parm] %s: ", SYMBOL_NAME (sym));
1238 add_register (collect, reg);
1239 /* check for doubles stored in two registers */
1240 /* FIXME: how about larger types stored in 3 or more regs? */
1241 if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FLT &&
1242 len > REGISTER_RAW_SIZE (reg))
1243 add_register (collect, reg + 1);
1244 break;
1245 case LOC_REF_ARG:
1246 printf_filtered ("Sorry, don't know how to do LOC_REF_ARG yet.\n");
1247 printf_filtered (" (will not collect %s)\n",
1248 SYMBOL_NAME (sym));
1249 break;
1250 case LOC_ARG:
1251 reg = frame_regno;
1252 offset = frame_offset + SYMBOL_VALUE (sym);
1253 if (info_verbose)
1254 {
1255 printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset ",
1256 SYMBOL_NAME (sym), len);
1257 printf_vma (offset);
1258 printf_filtered (" from frame ptr reg %d\n", reg);
1259 }
1260 add_memrange (collect, reg, offset, len);
1261 break;
1262 case LOC_REGPARM_ADDR:
1263 reg = SYMBOL_VALUE (sym);
1264 offset = 0;
1265 if (info_verbose)
1266 {
1267 printf_filtered ("LOC_REGPARM_ADDR %s: Collect %ld bytes at offset ",
1268 SYMBOL_NAME (sym), len);
1269 printf_vma (offset);
1270 printf_filtered (" from reg %d\n", reg);
1271 }
1272 add_memrange (collect, reg, offset, len);
1273 break;
1274 case LOC_LOCAL:
1275 case LOC_LOCAL_ARG:
1276 reg = frame_regno;
1277 offset = frame_offset + SYMBOL_VALUE (sym);
1278 if (info_verbose)
1279 {
1280 printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset ",
1281 SYMBOL_NAME (sym), len);
1282 printf_vma (offset);
1283 printf_filtered (" from frame ptr reg %d\n", reg);
1284 }
1285 add_memrange (collect, reg, offset, len);
1286 break;
1287 case LOC_BASEREG:
1288 case LOC_BASEREG_ARG:
1289 reg = SYMBOL_BASEREG (sym);
1290 offset = SYMBOL_VALUE (sym);
1291 if (info_verbose)
1292 {
1293 printf_filtered ("LOC_BASEREG %s: collect %ld bytes at offset ",
1294 SYMBOL_NAME (sym), len);
1295 printf_vma (offset);
1296 printf_filtered (" from basereg %d\n", reg);
1297 }
1298 add_memrange (collect, reg, offset, len);
1299 break;
1300 case LOC_UNRESOLVED:
1301 printf_filtered ("Don't know LOC_UNRESOLVED %s\n", SYMBOL_NAME (sym));
1302 break;
1303 case LOC_OPTIMIZED_OUT:
1304 printf_filtered ("%s has been optimized out of existance.\n",
1305 SYMBOL_NAME (sym));
1306 break;
1307 }
1308 }
1309
1310 /* Add all locals (or args) symbols to collection list */
1311 static void
1312 add_local_symbols (collect, pc, frame_regno, frame_offset, type)
1313 struct collection_list *collect;
1314 CORE_ADDR pc;
1315 long frame_regno;
1316 long frame_offset;
1317 int type;
1318 {
1319 struct symbol *sym;
1320 struct block *block;
1321 int i, nsyms, count = 0;
1322
1323 block = block_for_pc (pc);
1324 while (block != 0)
1325 {
1326 QUIT; /* allow user to bail out with ^C */
1327 nsyms = BLOCK_NSYMS (block);
1328 for (i = 0; i < nsyms; i++)
1329 {
1330 sym = BLOCK_SYM (block, i);
1331 switch (SYMBOL_CLASS (sym))
1332 {
1333 default:
1334 warning ("don't know how to trace local symbol %s",
1335 SYMBOL_NAME (sym));
1336 case LOC_LOCAL:
1337 case LOC_STATIC:
1338 case LOC_REGISTER:
1339 case LOC_BASEREG:
1340 if (type == 'L') /* collecting Locals */
1341 {
1342 count++;
1343 collect_symbol (collect, sym, frame_regno, frame_offset);
1344 }
1345 break;
1346 case LOC_ARG:
1347 case LOC_LOCAL_ARG:
1348 case LOC_REF_ARG:
1349 case LOC_REGPARM:
1350 case LOC_REGPARM_ADDR:
1351 case LOC_BASEREG_ARG:
1352 if (type == 'A') /* collecting Arguments */
1353 {
1354 count++;
1355 collect_symbol (collect, sym, frame_regno, frame_offset);
1356 }
1357 }
1358 }
1359 if (BLOCK_FUNCTION (block))
1360 break;
1361 else
1362 block = BLOCK_SUPERBLOCK (block);
1363 }
1364 if (count == 0)
1365 warning ("No %s found in scope.", type == 'L' ? "locals" : "args");
1366 }
1367
1368 /* worker function */
1369 static void
1370 clear_collection_list (list)
1371 struct collection_list *list;
1372 {
1373 int ndx;
1374
1375 list->next_memrange = 0;
1376 for (ndx = 0; ndx < list->next_aexpr_elt; ndx++)
1377 {
1378 free_agent_expr (list->aexpr_list[ndx]);
1379 list->aexpr_list[ndx] = NULL;
1380 }
1381 list->next_aexpr_elt = 0;
1382 memset (list->regs_mask, 0, sizeof (list->regs_mask));
1383 }
1384
1385 /* reduce a collection list to string form (for gdb protocol) */
1386 static char **
1387 stringify_collection_list (list, string)
1388 struct collection_list *list;
1389 char *string;
1390 {
1391 char temp_buf[2048];
1392 char tmp2[40];
1393 int count;
1394 int ndx = 0;
1395 char *(*str_list)[];
1396 char *end;
1397 long i;
1398
1399 count = 1 + list->next_memrange + list->next_aexpr_elt + 1;
1400 str_list = (char *(*)[]) xmalloc (count * sizeof (char *));
1401
1402 for (i = sizeof (list->regs_mask) - 1; i > 0; i--)
1403 if (list->regs_mask[i] != 0) /* skip leading zeroes in regs_mask */
1404 break;
1405 if (list->regs_mask[i] != 0) /* prepare to send regs_mask to the stub */
1406 {
1407 if (info_verbose)
1408 printf_filtered ("\nCollecting registers (mask): 0x");
1409 end = temp_buf;
1410 *end++ = 'R';
1411 for (; i >= 0; i--)
1412 {
1413 QUIT; /* allow user to bail out with ^C */
1414 if (info_verbose)
1415 printf_filtered ("%02X", list->regs_mask[i]);
1416 sprintf (end, "%02X", list->regs_mask[i]);
1417 end += 2;
1418 }
1419 (*str_list)[ndx] = savestring (temp_buf, end - temp_buf);
1420 ndx++;
1421 }
1422 if (info_verbose)
1423 printf_filtered ("\n");
1424 if (list->next_memrange > 0 && info_verbose)
1425 printf_filtered ("Collecting memranges: \n");
1426 for (i = 0, count = 0, end = temp_buf; i < list->next_memrange; i++)
1427 {
1428 QUIT; /* allow user to bail out with ^C */
1429 sprintf_vma (tmp2, list->list[i].start);
1430 if (info_verbose)
1431 {
1432 printf_filtered ("(%d, %s, %ld)\n",
1433 list->list[i].type,
1434 tmp2,
1435 (long) (list->list[i].end - list->list[i].start));
1436 }
1437 if (count + 27 > MAX_AGENT_EXPR_LEN)
1438 {
1439 (*str_list)[ndx] = savestring (temp_buf, count);
1440 ndx++;
1441 count = 0;
1442 end = temp_buf;
1443 }
1444
1445 sprintf (end, "M%X,%s,%lX",
1446 list->list[i].type,
1447 tmp2,
1448 (long) (list->list[i].end - list->list[i].start));
1449
1450 count += strlen (end);
1451 end += count;
1452 }
1453
1454 for (i = 0; i < list->next_aexpr_elt; i++)
1455 {
1456 QUIT; /* allow user to bail out with ^C */
1457 if ((count + 10 + 2 * list->aexpr_list[i]->len) > MAX_AGENT_EXPR_LEN)
1458 {
1459 (*str_list)[ndx] = savestring (temp_buf, count);
1460 ndx++;
1461 count = 0;
1462 end = temp_buf;
1463 }
1464 sprintf (end, "X%08X,", list->aexpr_list[i]->len);
1465 end += 10; /* 'X' + 8 hex digits + ',' */
1466 count += 10;
1467
1468 end = mem2hex (list->aexpr_list[i]->buf, end, list->aexpr_list[i]->len);
1469 count += 2 * list->aexpr_list[i]->len;
1470 }
1471
1472 if (count != 0)
1473 {
1474 (*str_list)[ndx] = savestring (temp_buf, count);
1475 ndx++;
1476 count = 0;
1477 end = temp_buf;
1478 }
1479 (*str_list)[ndx] = NULL;
1480
1481 if (ndx == 0)
1482 return NULL;
1483 else
1484 return *str_list;
1485 }
1486
1487 static void
1488 free_actions_list_cleanup_wrapper (al)
1489 void *al;
1490 {
1491 free_actions_list (al);
1492 }
1493
1494 static void
1495 free_actions_list (actions_list)
1496 char **actions_list;
1497 {
1498 int ndx;
1499
1500 if (actions_list == 0)
1501 return;
1502
1503 for (ndx = 0; actions_list[ndx]; ndx++)
1504 free (actions_list[ndx]);
1505
1506 free (actions_list);
1507 }
1508
1509 /* render all actions into gdb protocol */
1510 static void
1511 encode_actions (t, tdp_actions, stepping_actions)
1512 struct tracepoint *t;
1513 char ***tdp_actions;
1514 char ***stepping_actions;
1515 {
1516 static char tdp_buff[2048], step_buff[2048];
1517 char *action_exp;
1518 struct expression *exp = NULL;
1519 struct action_line *action;
1520 int i;
1521 value_ptr tempval;
1522 struct collection_list *collect;
1523 struct cmd_list_element *cmd;
1524 struct agent_expr *aexpr;
1525 long frame_reg, frame_offset;
1526
1527
1528 clear_collection_list (&tracepoint_list);
1529 clear_collection_list (&stepping_list);
1530 collect = &tracepoint_list;
1531
1532 *tdp_actions = NULL;
1533 *stepping_actions = NULL;
1534
1535 TARGET_VIRTUAL_FRAME_POINTER (t->address, &frame_reg, &frame_offset);
1536
1537 for (action = t->actions; action; action = action->next)
1538 {
1539 QUIT; /* allow user to bail out with ^C */
1540 action_exp = action->action;
1541 while (isspace ((int) *action_exp))
1542 action_exp++;
1543
1544 if (*action_exp == '#') /* comment line */
1545 return;
1546
1547 cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
1548 if (cmd == 0)
1549 error ("Bad action list item: %s", action_exp);
1550
1551 if (cmd->function.cfunc == collect_pseudocommand)
1552 {
1553 do
1554 { /* repeat over a comma-separated list */
1555 QUIT; /* allow user to bail out with ^C */
1556 while (isspace ((int) *action_exp))
1557 action_exp++;
1558
1559 if (0 == strncasecmp ("$reg", action_exp, 4))
1560 {
1561 for (i = 0; i < NUM_REGS; i++)
1562 add_register (collect, i);
1563 action_exp = strchr (action_exp, ','); /* more? */
1564 }
1565 else if (0 == strncasecmp ("$arg", action_exp, 4))
1566 {
1567 add_local_symbols (collect,
1568 t->address,
1569 frame_reg,
1570 frame_offset,
1571 'A');
1572 action_exp = strchr (action_exp, ','); /* more? */
1573 }
1574 else if (0 == strncasecmp ("$loc", action_exp, 4))
1575 {
1576 add_local_symbols (collect,
1577 t->address,
1578 frame_reg,
1579 frame_offset,
1580 'L');
1581 action_exp = strchr (action_exp, ','); /* more? */
1582 }
1583 else
1584 {
1585 unsigned long addr, len;
1586 struct cleanup *old_chain = NULL;
1587 struct cleanup *old_chain1 = NULL;
1588 struct agent_reqs areqs;
1589
1590 exp = parse_exp_1 (&action_exp, block_for_pc (t->address), 1);
1591 old_chain = make_cleanup ((make_cleanup_func)
1592 free_current_contents, &exp);
1593
1594 switch (exp->elts[0].opcode)
1595 {
1596 case OP_REGISTER:
1597 i = exp->elts[1].longconst;
1598 if (info_verbose)
1599 printf_filtered ("OP_REGISTER: ");
1600 add_register (collect, i);
1601 break;
1602
1603 case UNOP_MEMVAL:
1604 /* safe because we know it's a simple expression */
1605 tempval = evaluate_expression (exp);
1606 addr = VALUE_ADDRESS (tempval) + VALUE_OFFSET (tempval);
1607 len = TYPE_LENGTH (check_typedef (exp->elts[1].type));
1608 add_memrange (collect, -1, addr, len);
1609 break;
1610
1611 case OP_VAR_VALUE:
1612 collect_symbol (collect,
1613 exp->elts[2].symbol,
1614 frame_reg,
1615 frame_offset);
1616 break;
1617
1618 default: /* full-fledged expression */
1619 aexpr = gen_trace_for_expr (t->address, exp);
1620
1621 old_chain1 = make_cleanup ((make_cleanup_func)
1622 free_agent_expr, aexpr);
1623
1624 ax_reqs (aexpr, &areqs);
1625 if (areqs.flaw != agent_flaw_none)
1626 error ("malformed expression");
1627
1628 if (areqs.min_height < 0)
1629 error ("gdb: Internal error: expression has min height < 0");
1630 if (areqs.max_height > 20)
1631 error ("expression too complicated, try simplifying");
1632
1633 discard_cleanups (old_chain1);
1634 add_aexpr (collect, aexpr);
1635
1636 /* take care of the registers */
1637 if (areqs.reg_mask_len > 0)
1638 {
1639 int ndx1;
1640 int ndx2;
1641
1642 for (ndx1 = 0; ndx1 < areqs.reg_mask_len; ndx1++)
1643 {
1644 QUIT; /* allow user to bail out with ^C */
1645 if (areqs.reg_mask[ndx1] != 0)
1646 {
1647 /* assume chars have 8 bits */
1648 for (ndx2 = 0; ndx2 < 8; ndx2++)
1649 if (areqs.reg_mask[ndx1] & (1 << ndx2))
1650 /* it's used -- record it */
1651 add_register (collect, ndx1 * 8 + ndx2);
1652 }
1653 }
1654 }
1655 break;
1656 } /* switch */
1657 do_cleanups (old_chain);
1658 } /* do */
1659 }
1660 while (action_exp && *action_exp++ == ',');
1661 } /* if */
1662 else if (cmd->function.cfunc == while_stepping_pseudocommand)
1663 {
1664 collect = &stepping_list;
1665 }
1666 else if (cmd->function.cfunc == end_actions_pseudocommand)
1667 {
1668 if (collect == &stepping_list) /* end stepping actions */
1669 collect = &tracepoint_list;
1670 else
1671 break; /* end tracepoint actions */
1672 }
1673 } /* for */
1674 memrange_sortmerge (&tracepoint_list);
1675 memrange_sortmerge (&stepping_list);
1676
1677 *tdp_actions = stringify_collection_list (&tracepoint_list, &tdp_buff);
1678 *stepping_actions = stringify_collection_list (&stepping_list, &step_buff);
1679 }
1680
1681 static void
1682 add_aexpr (collect, aexpr)
1683 struct collection_list *collect;
1684 struct agent_expr *aexpr;
1685 {
1686 if (collect->next_aexpr_elt >= collect->aexpr_listsize)
1687 {
1688 collect->aexpr_list =
1689 xrealloc (collect->aexpr_list,
1690 2 * collect->aexpr_listsize * sizeof (struct agent_expr *));
1691 collect->aexpr_listsize *= 2;
1692 }
1693 collect->aexpr_list[collect->next_aexpr_elt] = aexpr;
1694 collect->next_aexpr_elt++;
1695 }
1696
1697 static char target_buf[2048];
1698
1699 /* Set "transparent" memory ranges
1700
1701 Allow trace mechanism to treat text-like sections
1702 (and perhaps all read-only sections) transparently,
1703 i.e. don't reject memory requests from these address ranges
1704 just because they haven't been collected. */
1705
1706 static void
1707 remote_set_transparent_ranges (void)
1708 {
1709 extern bfd *exec_bfd;
1710 asection *s;
1711 bfd_size_type size;
1712 bfd_vma lma;
1713 int anysecs = 0;
1714
1715 if (!exec_bfd)
1716 return; /* no information to give. */
1717
1718 strcpy (target_buf, "QTro");
1719 for (s = exec_bfd->sections; s; s = s->next)
1720 {
1721 char tmp1[40], tmp2[40];
1722
1723 if ((s->flags & SEC_LOAD) == 0 ||
1724 /* (s->flags & SEC_CODE) == 0 || */
1725 (s->flags & SEC_READONLY) == 0)
1726 continue;
1727
1728 anysecs = 1;
1729 lma = s->lma;
1730 size = bfd_get_section_size_before_reloc (s);
1731 sprintf_vma (tmp1, lma);
1732 sprintf_vma (tmp2, lma + size);
1733 sprintf (target_buf + strlen (target_buf),
1734 ":%s,%s", tmp1, tmp2);
1735 }
1736 if (anysecs)
1737 {
1738 putpkt (target_buf);
1739 getpkt (target_buf, sizeof (target_buf), 0);
1740 }
1741 }
1742
1743 /* tstart command:
1744
1745 Tell target to clear any previous trace experiment.
1746 Walk the list of tracepoints, and send them (and their actions)
1747 to the target. If no errors,
1748 Tell target to start a new trace experiment. */
1749
1750 static void
1751 trace_start_command (args, from_tty)
1752 char *args;
1753 int from_tty;
1754 { /* STUB_COMM MOSTLY_IMPLEMENTED */
1755 struct tracepoint *t;
1756 char buf[2048];
1757 char **tdp_actions;
1758 char **stepping_actions;
1759 int ndx;
1760 struct cleanup *old_chain = NULL;
1761
1762 dont_repeat (); /* like "run", dangerous to repeat accidentally */
1763
1764 if (target_is_remote ())
1765 {
1766 putpkt ("QTinit");
1767 remote_get_noisy_reply (target_buf, sizeof (target_buf));
1768 if (strcmp (target_buf, "OK"))
1769 error ("Target does not support this command.");
1770
1771 ALL_TRACEPOINTS (t)
1772 {
1773 char tmp[40];
1774
1775 sprintf_vma (tmp, t->address);
1776 sprintf (buf, "QTDP:%x:%s:%c:%x:%x", t->number, tmp, /* address */
1777 t->enabled == enabled ? 'E' : 'D',
1778 t->step_count, t->pass_count);
1779
1780 if (t->actions)
1781 strcat (buf, "-");
1782 putpkt (buf);
1783 remote_get_noisy_reply (target_buf, sizeof (target_buf));
1784 if (strcmp (target_buf, "OK"))
1785 error ("Target does not support tracepoints.");
1786
1787 if (t->actions)
1788 {
1789 encode_actions (t, &tdp_actions, &stepping_actions);
1790 old_chain = make_cleanup (free_actions_list_cleanup_wrapper,
1791 tdp_actions);
1792 (void) make_cleanup (free_actions_list_cleanup_wrapper,
1793 stepping_actions);
1794
1795 /* do_single_steps (t); */
1796 if (tdp_actions)
1797 {
1798 for (ndx = 0; tdp_actions[ndx]; ndx++)
1799 {
1800 QUIT; /* allow user to bail out with ^C */
1801 sprintf (buf, "QTDP:-%x:%s:%s%c",
1802 t->number, tmp, /* address */
1803 tdp_actions[ndx],
1804 ((tdp_actions[ndx + 1] || stepping_actions)
1805 ? '-' : 0));
1806 putpkt (buf);
1807 remote_get_noisy_reply (target_buf, sizeof (target_buf));
1808 if (strcmp (target_buf, "OK"))
1809 error ("Error on target while setting tracepoints.");
1810 }
1811 }
1812 if (stepping_actions)
1813 {
1814 for (ndx = 0; stepping_actions[ndx]; ndx++)
1815 {
1816 QUIT; /* allow user to bail out with ^C */
1817 sprintf (buf, "QTDP:-%x:%s:%s%s%s",
1818 t->number, tmp, /* address */
1819 ((ndx == 0) ? "S" : ""),
1820 stepping_actions[ndx],
1821 (stepping_actions[ndx + 1] ? "-" : ""));
1822 putpkt (buf);
1823 remote_get_noisy_reply (target_buf, sizeof (target_buf));
1824 if (strcmp (target_buf, "OK"))
1825 error ("Error on target while setting tracepoints.");
1826 }
1827 }
1828
1829 do_cleanups (old_chain);
1830 }
1831 }
1832 /* Tell target to treat text-like sections as transparent */
1833 remote_set_transparent_ranges ();
1834 /* Now insert traps and begin collecting data */
1835 putpkt ("QTStart");
1836 remote_get_noisy_reply (target_buf, sizeof (target_buf));
1837 if (strcmp (target_buf, "OK"))
1838 error ("Bogus reply from target: %s", target_buf);
1839 set_traceframe_num (-1); /* all old traceframes invalidated */
1840 set_tracepoint_num (-1);
1841 set_traceframe_context (-1);
1842 trace_running_p = 1;
1843 if (trace_start_stop_hook)
1844 trace_start_stop_hook (1, from_tty);
1845
1846 }
1847 else
1848 error ("Trace can only be run on remote targets.");
1849 }
1850
1851 /* tstop command */
1852 static void
1853 trace_stop_command (args, from_tty)
1854 char *args;
1855 int from_tty;
1856 { /* STUB_COMM IS_IMPLEMENTED */
1857 if (target_is_remote ())
1858 {
1859 putpkt ("QTStop");
1860 remote_get_noisy_reply (target_buf, sizeof (target_buf));
1861 if (strcmp (target_buf, "OK"))
1862 error ("Bogus reply from target: %s", target_buf);
1863 trace_running_p = 0;
1864 if (trace_start_stop_hook)
1865 trace_start_stop_hook (0, from_tty);
1866 }
1867 else
1868 error ("Trace can only be run on remote targets.");
1869 }
1870
1871 unsigned long trace_running_p;
1872
1873 /* tstatus command */
1874 static void
1875 trace_status_command (args, from_tty)
1876 char *args;
1877 int from_tty;
1878 { /* STUB_COMM IS_IMPLEMENTED */
1879 if (target_is_remote ())
1880 {
1881 putpkt ("qTStatus");
1882 remote_get_noisy_reply (target_buf, sizeof (target_buf));
1883
1884 if (target_buf[0] != 'T' ||
1885 (target_buf[1] != '0' && target_buf[1] != '1'))
1886 error ("Bogus reply from target: %s", target_buf);
1887
1888 /* exported for use by the GUI */
1889 trace_running_p = (target_buf[1] == '1');
1890 }
1891 else
1892 error ("Trace can only be run on remote targets.");
1893 }
1894
1895 /* Worker function for the various flavors of the tfind command */
1896 static void
1897 finish_tfind_command (char *msg,
1898 long sizeof_msg,
1899 int from_tty)
1900 {
1901 int target_frameno = -1, target_tracept = -1;
1902 CORE_ADDR old_frame_addr;
1903 struct symbol *old_func;
1904 char *reply;
1905
1906 old_frame_addr = FRAME_FP (get_current_frame ());
1907 old_func = find_pc_function (read_pc ());
1908
1909 putpkt (msg);
1910 reply = remote_get_noisy_reply (msg, sizeof_msg);
1911
1912 while (reply && *reply)
1913 switch (*reply)
1914 {
1915 case 'F':
1916 if ((target_frameno = (int) strtol (++reply, &reply, 16)) == -1)
1917 {
1918 /* A request for a non-existant trace frame has failed.
1919 Our response will be different, depending on FROM_TTY:
1920
1921 If FROM_TTY is true, meaning that this command was
1922 typed interactively by the user, then give an error
1923 and DO NOT change the state of traceframe_number etc.
1924
1925 However if FROM_TTY is false, meaning that we're either
1926 in a script, a loop, or a user-defined command, then
1927 DON'T give an error, but DO change the state of
1928 traceframe_number etc. to invalid.
1929
1930 The rationalle is that if you typed the command, you
1931 might just have committed a typo or something, and you'd
1932 like to NOT lose your current debugging state. However
1933 if you're in a user-defined command or especially in a
1934 loop, then you need a way to detect that the command
1935 failed WITHOUT aborting. This allows you to write
1936 scripts that search thru the trace buffer until the end,
1937 and then continue on to do something else. */
1938
1939 if (from_tty)
1940 error ("Target failed to find requested trace frame.");
1941 else
1942 {
1943 if (info_verbose)
1944 printf_filtered ("End of trace buffer.\n");
1945 /* The following will not recurse, since it's special-cased */
1946 trace_find_command ("-1", from_tty);
1947 reply = NULL; /* break out of loop,
1948 (avoid recursive nonsense) */
1949 }
1950 }
1951 break;
1952 case 'T':
1953 if ((target_tracept = (int) strtol (++reply, &reply, 16)) == -1)
1954 error ("Target failed to find requested trace frame.");
1955 break;
1956 case 'O': /* "OK"? */
1957 if (reply[1] == 'K' && reply[2] == '\0')
1958 reply += 2;
1959 else
1960 error ("Bogus reply from target: %s", reply);
1961 break;
1962 default:
1963 error ("Bogus reply from target: %s", reply);
1964 }
1965
1966 flush_cached_frames ();
1967 registers_changed ();
1968 select_frame (get_current_frame (), 0);
1969 set_traceframe_num (target_frameno);
1970 set_tracepoint_num (target_tracept);
1971 if (target_frameno == -1)
1972 set_traceframe_context (-1);
1973 else
1974 set_traceframe_context (read_pc ());
1975
1976 if (from_tty)
1977 {
1978 int source_only;
1979
1980 /* NOTE: in immitation of the step command, try to determine
1981 whether we have made a transition from one function to another.
1982 If so, we'll print the "stack frame" (ie. the new function and
1983 it's arguments) -- otherwise we'll just show the new source line.
1984
1985 This determination is made by checking (1) whether the current
1986 function has changed, and (2) whether the current FP has changed.
1987 Hack: if the FP wasn't collected, either at the current or the
1988 previous frame, assume that the FP has NOT changed. */
1989
1990 if (old_func == find_pc_function (read_pc ()) &&
1991 (old_frame_addr == 0 ||
1992 FRAME_FP (get_current_frame ()) == 0 ||
1993 old_frame_addr == FRAME_FP (get_current_frame ())))
1994 source_only = -1;
1995 else
1996 source_only = 1;
1997
1998 print_stack_frame (selected_frame, selected_frame_level, source_only);
1999 do_displays ();
2000 }
2001 }
2002
2003 /* trace_find_command takes a trace frame number n,
2004 sends "QTFrame:<n>" to the target,
2005 and accepts a reply that may contain several optional pieces
2006 of information: a frame number, a tracepoint number, and an
2007 indication of whether this is a trap frame or a stepping frame.
2008
2009 The minimal response is just "OK" (which indicates that the
2010 target does not give us a frame number or a tracepoint number).
2011 Instead of that, the target may send us a string containing
2012 any combination of:
2013 F<hexnum> (gives the selected frame number)
2014 T<hexnum> (gives the selected tracepoint number)
2015 */
2016
2017 /* tfind command */
2018 static void
2019 trace_find_command (args, from_tty)
2020 char *args;
2021 int from_tty;
2022 { /* STUB_COMM PART_IMPLEMENTED */
2023 /* this should only be called with a numeric argument */
2024 int frameno = -1;
2025
2026 if (target_is_remote ())
2027 {
2028 if (trace_find_hook)
2029 trace_find_hook (args, from_tty);
2030
2031 if (args == 0 || *args == 0)
2032 { /* TFIND with no args means find NEXT trace frame. */
2033 if (traceframe_number == -1)
2034 frameno = 0; /* "next" is first one */
2035 else
2036 frameno = traceframe_number + 1;
2037 }
2038 else if (0 == strcmp (args, "-"))
2039 {
2040 if (traceframe_number == -1)
2041 error ("not debugging trace buffer");
2042 else if (from_tty && traceframe_number == 0)
2043 error ("already at start of trace buffer");
2044
2045 frameno = traceframe_number - 1;
2046 }
2047 else
2048 frameno = parse_and_eval_address (args);
2049
2050 if (frameno < -1)
2051 error ("invalid input (%d is less than zero)", frameno);
2052
2053 sprintf (target_buf, "QTFrame:%x", frameno);
2054 finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
2055 }
2056 else
2057 error ("Trace can only be run on remote targets.");
2058 }
2059
2060 /* tfind end */
2061 static void
2062 trace_find_end_command (args, from_tty)
2063 char *args;
2064 int from_tty;
2065 {
2066 trace_find_command ("-1", from_tty);
2067 }
2068
2069 /* tfind none */
2070 static void
2071 trace_find_none_command (args, from_tty)
2072 char *args;
2073 int from_tty;
2074 {
2075 trace_find_command ("-1", from_tty);
2076 }
2077
2078 /* tfind start */
2079 static void
2080 trace_find_start_command (args, from_tty)
2081 char *args;
2082 int from_tty;
2083 {
2084 trace_find_command ("0", from_tty);
2085 }
2086
2087 /* tfind pc command */
2088 static void
2089 trace_find_pc_command (args, from_tty)
2090 char *args;
2091 int from_tty;
2092 { /* STUB_COMM PART_IMPLEMENTED */
2093 CORE_ADDR pc;
2094 char tmp[40];
2095
2096 if (target_is_remote ())
2097 {
2098 if (args == 0 || *args == 0)
2099 pc = read_pc (); /* default is current pc */
2100 else
2101 pc = parse_and_eval_address (args);
2102
2103 sprintf_vma (tmp, pc);
2104 sprintf (target_buf, "QTFrame:pc:%s", tmp);
2105 finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
2106 }
2107 else
2108 error ("Trace can only be run on remote targets.");
2109 }
2110
2111 /* tfind tracepoint command */
2112 static void
2113 trace_find_tracepoint_command (args, from_tty)
2114 char *args;
2115 int from_tty;
2116 { /* STUB_COMM PART_IMPLEMENTED */
2117 int tdp;
2118
2119 if (target_is_remote ())
2120 {
2121 if (args == 0 || *args == 0)
2122 if (tracepoint_number == -1)
2123 error ("No current tracepoint -- please supply an argument.");
2124 else
2125 tdp = tracepoint_number; /* default is current TDP */
2126 else
2127 tdp = parse_and_eval_address (args);
2128
2129 sprintf (target_buf, "QTFrame:tdp:%x", tdp);
2130 finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
2131 }
2132 else
2133 error ("Trace can only be run on remote targets.");
2134 }
2135
2136 /* TFIND LINE command:
2137
2138 This command will take a sourceline for argument, just like BREAK
2139 or TRACE (ie. anything that "decode_line_1" can handle).
2140
2141 With no argument, this command will find the next trace frame
2142 corresponding to a source line OTHER THAN THE CURRENT ONE. */
2143
2144 static void
2145 trace_find_line_command (args, from_tty)
2146 char *args;
2147 int from_tty;
2148 { /* STUB_COMM PART_IMPLEMENTED */
2149 static CORE_ADDR start_pc, end_pc;
2150 struct symtabs_and_lines sals;
2151 struct symtab_and_line sal;
2152 struct cleanup *old_chain;
2153 char startpc_str[40], endpc_str[40];
2154
2155 if (target_is_remote ())
2156 {
2157 if (args == 0 || *args == 0)
2158 {
2159 sal = find_pc_line ((get_current_frame ())->pc, 0);
2160 sals.nelts = 1;
2161 sals.sals = (struct symtab_and_line *)
2162 xmalloc (sizeof (struct symtab_and_line));
2163 sals.sals[0] = sal;
2164 }
2165 else
2166 {
2167 sals = decode_line_spec (args, 1);
2168 sal = sals.sals[0];
2169 }
2170
2171 old_chain = make_cleanup (free, sals.sals);
2172 if (sal.symtab == 0)
2173 {
2174 printf_filtered ("TFIND: No line number information available");
2175 if (sal.pc != 0)
2176 {
2177 /* This is useful for "info line *0x7f34". If we can't tell the
2178 user about a source line, at least let them have the symbolic
2179 address. */
2180 printf_filtered (" for address ");
2181 wrap_here (" ");
2182 print_address (sal.pc, gdb_stdout);
2183 printf_filtered (";\n -- will attempt to find by PC. \n");
2184 }
2185 else
2186 {
2187 printf_filtered (".\n");
2188 return; /* no line, no PC; what can we do? */
2189 }
2190 }
2191 else if (sal.line > 0
2192 && find_line_pc_range (sal, &start_pc, &end_pc))
2193 {
2194 if (start_pc == end_pc)
2195 {
2196 printf_filtered ("Line %d of \"%s\"",
2197 sal.line, sal.symtab->filename);
2198 wrap_here (" ");
2199 printf_filtered (" is at address ");
2200 print_address (start_pc, gdb_stdout);
2201 wrap_here (" ");
2202 printf_filtered (" but contains no code.\n");
2203 sal = find_pc_line (start_pc, 0);
2204 if (sal.line > 0 &&
2205 find_line_pc_range (sal, &start_pc, &end_pc) &&
2206 start_pc != end_pc)
2207 printf_filtered ("Attempting to find line %d instead.\n",
2208 sal.line);
2209 else
2210 error ("Cannot find a good line.");
2211 }
2212 }
2213 else
2214 /* Is there any case in which we get here, and have an address
2215 which the user would want to see? If we have debugging symbols
2216 and no line numbers? */
2217 error ("Line number %d is out of range for \"%s\".\n",
2218 sal.line, sal.symtab->filename);
2219
2220 sprintf_vma (startpc_str, start_pc);
2221 sprintf_vma (endpc_str, end_pc - 1);
2222 if (args && *args) /* find within range of stated line */
2223 sprintf (target_buf, "QTFrame:range:%s:%s", startpc_str, endpc_str);
2224 else /* find OUTSIDE OF range of CURRENT line */
2225 sprintf (target_buf, "QTFrame:outside:%s:%s", startpc_str, endpc_str);
2226 finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
2227 do_cleanups (old_chain);
2228 }
2229 else
2230 error ("Trace can only be run on remote targets.");
2231 }
2232
2233 /* tfind range command */
2234 static void
2235 trace_find_range_command (args, from_tty)
2236 char *args;
2237 int from_tty;
2238 {
2239 static CORE_ADDR start, stop;
2240 char start_str[40], stop_str[40];
2241 char *tmp;
2242
2243 if (target_is_remote ())
2244 {
2245 if (args == 0 || *args == 0)
2246 { /* XXX FIXME: what should default behavior be? */
2247 printf_filtered ("Usage: tfind range <startaddr>,<endaddr>\n");
2248 return;
2249 }
2250
2251 if (0 != (tmp = strchr (args, ',')))
2252 {
2253 *tmp++ = '\0'; /* terminate start address */
2254 while (isspace ((int) *tmp))
2255 tmp++;
2256 start = parse_and_eval_address (args);
2257 stop = parse_and_eval_address (tmp);
2258 }
2259 else
2260 { /* no explicit end address? */
2261 start = parse_and_eval_address (args);
2262 stop = start + 1; /* ??? */
2263 }
2264
2265 sprintf_vma (start_str, start);
2266 sprintf_vma (stop_str, stop);
2267 sprintf (target_buf, "QTFrame:range:%s:%s", start_str, stop_str);
2268 finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
2269 }
2270 else
2271 error ("Trace can only be run on remote targets.");
2272 }
2273
2274 /* tfind outside command */
2275 static void
2276 trace_find_outside_command (args, from_tty)
2277 char *args;
2278 int from_tty;
2279 {
2280 CORE_ADDR start, stop;
2281 char start_str[40], stop_str[40];
2282 char *tmp;
2283
2284 if (target_is_remote ())
2285 {
2286 if (args == 0 || *args == 0)
2287 { /* XXX FIXME: what should default behavior be? */
2288 printf_filtered ("Usage: tfind outside <startaddr>,<endaddr>\n");
2289 return;
2290 }
2291
2292 if (0 != (tmp = strchr (args, ',')))
2293 {
2294 *tmp++ = '\0'; /* terminate start address */
2295 while (isspace ((int) *tmp))
2296 tmp++;
2297 start = parse_and_eval_address (args);
2298 stop = parse_and_eval_address (tmp);
2299 }
2300 else
2301 { /* no explicit end address? */
2302 start = parse_and_eval_address (args);
2303 stop = start + 1; /* ??? */
2304 }
2305
2306 sprintf_vma (start_str, start);
2307 sprintf_vma (stop_str, stop);
2308 sprintf (target_buf, "QTFrame:outside:%s:%s", start_str, stop_str);
2309 finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
2310 }
2311 else
2312 error ("Trace can only be run on remote targets.");
2313 }
2314
2315 /* save-tracepoints command */
2316 static void
2317 tracepoint_save_command (args, from_tty)
2318 char *args;
2319 int from_tty;
2320 {
2321 struct tracepoint *tp;
2322 struct action_line *line;
2323 FILE *fp;
2324 char *i1 = " ", *i2 = " ";
2325 char *indent, *actionline;
2326 char tmp[40];
2327
2328 if (args == 0 || *args == 0)
2329 error ("Argument required (file name in which to save tracepoints");
2330
2331 if (tracepoint_chain == 0)
2332 {
2333 warning ("save-tracepoints: no tracepoints to save.\n");
2334 return;
2335 }
2336
2337 if (!(fp = fopen (args, "w")))
2338 error ("Unable to open file '%s' for saving tracepoints");
2339
2340 ALL_TRACEPOINTS (tp)
2341 {
2342 if (tp->addr_string)
2343 fprintf (fp, "trace %s\n", tp->addr_string);
2344 else
2345 {
2346 sprintf_vma (tmp, tp->address);
2347 fprintf (fp, "trace *0x%s\n", tmp);
2348 }
2349
2350 if (tp->pass_count)
2351 fprintf (fp, " passcount %d\n", tp->pass_count);
2352
2353 if (tp->actions)
2354 {
2355 fprintf (fp, " actions\n");
2356 indent = i1;
2357 for (line = tp->actions; line; line = line->next)
2358 {
2359 struct cmd_list_element *cmd;
2360
2361 QUIT; /* allow user to bail out with ^C */
2362 actionline = line->action;
2363 while (isspace ((int) *actionline))
2364 actionline++;
2365
2366 fprintf (fp, "%s%s\n", indent, actionline);
2367 if (*actionline != '#') /* skip for comment lines */
2368 {
2369 cmd = lookup_cmd (&actionline, cmdlist, "", -1, 1);
2370 if (cmd == 0)
2371 error ("Bad action list item: %s", actionline);
2372 if (cmd->function.cfunc == while_stepping_pseudocommand)
2373 indent = i2;
2374 else if (cmd->function.cfunc == end_actions_pseudocommand)
2375 indent = i1;
2376 }
2377 }
2378 }
2379 }
2380 fclose (fp);
2381 if (from_tty)
2382 printf_filtered ("Tracepoints saved to file '%s'.\n", args);
2383 return;
2384 }
2385
2386 /* info scope command: list the locals for a scope. */
2387 static void
2388 scope_info (args, from_tty)
2389 char *args;
2390 int from_tty;
2391 {
2392 struct symtabs_and_lines sals;
2393 struct symbol *sym;
2394 struct minimal_symbol *msym;
2395 struct block *block;
2396 char **canonical, *symname, *save_args = args;
2397 int i, j, nsyms, count = 0;
2398
2399 if (args == 0 || *args == 0)
2400 error ("requires an argument (function, line or *addr) to define a scope");
2401
2402 sals = decode_line_1 (&args, 1, NULL, 0, &canonical);
2403 if (sals.nelts == 0)
2404 return; /* presumably decode_line_1 has already warned */
2405
2406 /* Resolve line numbers to PC */
2407 resolve_sal_pc (&sals.sals[0]);
2408 block = block_for_pc (sals.sals[0].pc);
2409
2410 while (block != 0)
2411 {
2412 QUIT; /* allow user to bail out with ^C */
2413 nsyms = BLOCK_NSYMS (block);
2414 for (i = 0; i < nsyms; i++)
2415 {
2416 QUIT; /* allow user to bail out with ^C */
2417 if (count == 0)
2418 printf_filtered ("Scope for %s:\n", save_args);
2419 count++;
2420 sym = BLOCK_SYM (block, i);
2421 symname = SYMBOL_NAME (sym);
2422 if (symname == NULL || *symname == '\0')
2423 continue; /* probably botched, certainly useless */
2424
2425 printf_filtered ("Symbol %s is ", symname);
2426 switch (SYMBOL_CLASS (sym))
2427 {
2428 default:
2429 case LOC_UNDEF: /* messed up symbol? */
2430 printf_filtered ("a bogus symbol, class %d.\n",
2431 SYMBOL_CLASS (sym));
2432 count--; /* don't count this one */
2433 continue;
2434 case LOC_CONST:
2435 printf_filtered ("a constant with value %ld (0x%lx)",
2436 SYMBOL_VALUE (sym), SYMBOL_VALUE (sym));
2437 break;
2438 case LOC_CONST_BYTES:
2439 printf_filtered ("constant bytes: ");
2440 if (SYMBOL_TYPE (sym))
2441 for (j = 0; j < TYPE_LENGTH (SYMBOL_TYPE (sym)); j++)
2442 fprintf_filtered (gdb_stdout, " %02x",
2443 (unsigned) SYMBOL_VALUE_BYTES (sym)[j]);
2444 break;
2445 case LOC_STATIC:
2446 printf_filtered ("in static storage at address ");
2447 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym), 1, gdb_stdout);
2448 break;
2449 case LOC_REGISTER:
2450 printf_filtered ("a local variable in register $%s",
2451 REGISTER_NAME (SYMBOL_VALUE (sym)));
2452 break;
2453 case LOC_ARG:
2454 case LOC_LOCAL_ARG:
2455 printf_filtered ("an argument at stack/frame offset %ld",
2456 SYMBOL_VALUE (sym));
2457 break;
2458 case LOC_LOCAL:
2459 printf_filtered ("a local variable at frame offset %ld",
2460 SYMBOL_VALUE (sym));
2461 break;
2462 case LOC_REF_ARG:
2463 printf_filtered ("a reference argument at offset %ld",
2464 SYMBOL_VALUE (sym));
2465 break;
2466 case LOC_REGPARM:
2467 printf_filtered ("an argument in register $%s",
2468 REGISTER_NAME (SYMBOL_VALUE (sym)));
2469 break;
2470 case LOC_REGPARM_ADDR:
2471 printf_filtered ("the address of an argument, in register $%s",
2472 REGISTER_NAME (SYMBOL_VALUE (sym)));
2473 break;
2474 case LOC_TYPEDEF:
2475 printf_filtered ("a typedef.\n");
2476 continue;
2477 case LOC_LABEL:
2478 printf_filtered ("a label at address ");
2479 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym), 1, gdb_stdout);
2480 break;
2481 case LOC_BLOCK:
2482 printf_filtered ("a function at address ");
2483 print_address_numeric (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)), 1,
2484 gdb_stdout);
2485 break;
2486 case LOC_BASEREG:
2487 printf_filtered ("a variable at offset %ld from register $%s",
2488 SYMBOL_VALUE (sym),
2489 REGISTER_NAME (SYMBOL_BASEREG (sym)));
2490 break;
2491 case LOC_BASEREG_ARG:
2492 printf_filtered ("an argument at offset %ld from register $%s",
2493 SYMBOL_VALUE (sym),
2494 REGISTER_NAME (SYMBOL_BASEREG (sym)));
2495 break;
2496 case LOC_UNRESOLVED:
2497 msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, NULL);
2498 if (msym == NULL)
2499 printf_filtered ("Unresolved Static");
2500 else
2501 {
2502 printf_filtered ("static storage at address ");
2503 print_address_numeric (SYMBOL_VALUE_ADDRESS (msym), 1,
2504 gdb_stdout);
2505 }
2506 break;
2507 case LOC_OPTIMIZED_OUT:
2508 printf_filtered ("optimized out.\n");
2509 continue;
2510 }
2511 if (SYMBOL_TYPE (sym))
2512 printf_filtered (", length %d.\n",
2513 TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym))));
2514 }
2515 if (BLOCK_FUNCTION (block))
2516 break;
2517 else
2518 block = BLOCK_SUPERBLOCK (block);
2519 }
2520 if (count <= 0)
2521 printf_filtered ("Scope for %s contains no locals or arguments.\n",
2522 save_args);
2523 }
2524
2525 /* worker function (cleanup) */
2526 static void
2527 replace_comma (comma)
2528 char *comma;
2529 {
2530 *comma = ',';
2531 }
2532
2533 /* tdump command */
2534 static void
2535 trace_dump_command (args, from_tty)
2536 char *args;
2537 int from_tty;
2538 {
2539 struct tracepoint *t;
2540 struct action_line *action;
2541 char *action_exp, *next_comma;
2542 struct cleanup *old_cleanups;
2543 int stepping_actions = 0;
2544 int stepping_frame = 0;
2545
2546 if (!target_is_remote ())
2547 {
2548 error ("Trace can only be run on remote targets.");
2549 return;
2550 }
2551
2552 if (tracepoint_number == -1)
2553 {
2554 warning ("No current trace frame.");
2555 return;
2556 }
2557
2558 ALL_TRACEPOINTS (t)
2559 if (t->number == tracepoint_number)
2560 break;
2561
2562 if (t == NULL)
2563 error ("No known tracepoint matches 'current' tracepoint #%d.",
2564 tracepoint_number);
2565
2566 old_cleanups = make_cleanup (null_cleanup, NULL);
2567
2568 printf_filtered ("Data collected at tracepoint %d, trace frame %d:\n",
2569 tracepoint_number, traceframe_number);
2570
2571 /* The current frame is a trap frame if the frame PC is equal
2572 to the tracepoint PC. If not, then the current frame was
2573 collected during single-stepping. */
2574
2575 stepping_frame = (t->address != read_pc ());
2576
2577 for (action = t->actions; action; action = action->next)
2578 {
2579 struct cmd_list_element *cmd;
2580
2581 QUIT; /* allow user to bail out with ^C */
2582 action_exp = action->action;
2583 while (isspace ((int) *action_exp))
2584 action_exp++;
2585
2586 /* The collection actions to be done while stepping are
2587 bracketed by the commands "while-stepping" and "end". */
2588
2589 if (*action_exp == '#') /* comment line */
2590 continue;
2591
2592 cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
2593 if (cmd == 0)
2594 error ("Bad action list item: %s", action_exp);
2595
2596 if (cmd->function.cfunc == while_stepping_pseudocommand)
2597 stepping_actions = 1;
2598 else if (cmd->function.cfunc == end_actions_pseudocommand)
2599 stepping_actions = 0;
2600 else if (cmd->function.cfunc == collect_pseudocommand)
2601 {
2602 /* Display the collected data.
2603 For the trap frame, display only what was collected at the trap.
2604 Likewise for stepping frames, display only what was collected
2605 while stepping. This means that the two boolean variables,
2606 STEPPING_FRAME and STEPPING_ACTIONS should be equal. */
2607 if (stepping_frame == stepping_actions)
2608 {
2609 do
2610 { /* repeat over a comma-separated list */
2611 QUIT; /* allow user to bail out with ^C */
2612 if (*action_exp == ',')
2613 action_exp++;
2614 while (isspace ((int) *action_exp))
2615 action_exp++;
2616
2617 next_comma = strchr (action_exp, ',');
2618
2619 if (0 == strncasecmp (action_exp, "$reg", 4))
2620 registers_info (NULL, from_tty);
2621 else if (0 == strncasecmp (action_exp, "$loc", 4))
2622 locals_info (NULL, from_tty);
2623 else if (0 == strncasecmp (action_exp, "$arg", 4))
2624 args_info (NULL, from_tty);
2625 else
2626 { /* variable */
2627 if (next_comma)
2628 {
2629 make_cleanup (replace_comma, next_comma);
2630 *next_comma = '\0';
2631 }
2632 printf_filtered ("%s = ", action_exp);
2633 output_command (action_exp, from_tty);
2634 printf_filtered ("\n");
2635 }
2636 if (next_comma)
2637 *next_comma = ',';
2638 action_exp = next_comma;
2639 }
2640 while (action_exp && *action_exp == ',');
2641 }
2642 }
2643 }
2644 discard_cleanups (old_cleanups);
2645 }
2646
2647 /* Convert the memory pointed to by mem into hex, placing result in buf.
2648 * Return a pointer to the last char put in buf (null)
2649 * "stolen" from sparc-stub.c
2650 */
2651
2652 static const char hexchars[] = "0123456789abcdef";
2653
2654 static unsigned char *
2655 mem2hex (mem, buf, count)
2656 unsigned char *mem;
2657 unsigned char *buf;
2658 int count;
2659 {
2660 unsigned char ch;
2661
2662 while (count-- > 0)
2663 {
2664 ch = *mem++;
2665
2666 *buf++ = hexchars[ch >> 4];
2667 *buf++ = hexchars[ch & 0xf];
2668 }
2669
2670 *buf = 0;
2671
2672 return buf;
2673 }
2674
2675 int
2676 get_traceframe_number ()
2677 {
2678 return traceframe_number;
2679 }
2680
2681
2682 /* module initialization */
2683 void
2684 _initialize_tracepoint ()
2685 {
2686 tracepoint_chain = 0;
2687 tracepoint_count = 0;
2688 traceframe_number = -1;
2689 tracepoint_number = -1;
2690
2691 set_internalvar (lookup_internalvar ("tpnum"),
2692 value_from_longest (builtin_type_int, (LONGEST) 0));
2693 set_internalvar (lookup_internalvar ("trace_frame"),
2694 value_from_longest (builtin_type_int, (LONGEST) - 1));
2695
2696 if (tracepoint_list.list == NULL)
2697 {
2698 tracepoint_list.listsize = 128;
2699 tracepoint_list.list = xmalloc
2700 (tracepoint_list.listsize * sizeof (struct memrange));
2701 }
2702 if (tracepoint_list.aexpr_list == NULL)
2703 {
2704 tracepoint_list.aexpr_listsize = 128;
2705 tracepoint_list.aexpr_list = xmalloc
2706 (tracepoint_list.aexpr_listsize * sizeof (struct agent_expr *));
2707 }
2708
2709 if (stepping_list.list == NULL)
2710 {
2711 stepping_list.listsize = 128;
2712 stepping_list.list = xmalloc
2713 (stepping_list.listsize * sizeof (struct memrange));
2714 }
2715
2716 if (stepping_list.aexpr_list == NULL)
2717 {
2718 stepping_list.aexpr_listsize = 128;
2719 stepping_list.aexpr_list = xmalloc
2720 (stepping_list.aexpr_listsize * sizeof (struct agent_expr *));
2721 }
2722
2723 add_info ("scope", scope_info,
2724 "List the variables local to a scope");
2725
2726 add_cmd ("tracepoints", class_trace, NO_FUNCTION,
2727 "Tracing of program execution without stopping the program.",
2728 &cmdlist);
2729
2730 add_info ("tracepoints", tracepoints_info,
2731 "Status of tracepoints, or tracepoint number NUMBER.\n\
2732 Convenience variable \"$tpnum\" contains the number of the\n\
2733 last tracepoint set.");
2734
2735 add_info_alias ("tp", "tracepoints", 1);
2736
2737 add_com ("save-tracepoints", class_trace, tracepoint_save_command,
2738 "Save current tracepoint definitions as a script.\n\
2739 Use the 'source' command in another debug session to restore them.");
2740
2741 add_com ("tdump", class_trace, trace_dump_command,
2742 "Print everything collected at the current tracepoint.");
2743
2744 add_prefix_cmd ("tfind", class_trace, trace_find_command,
2745 "Select a trace frame;\n\
2746 No argument means forward by one frame; '-' meand backward by one frame.",
2747 &tfindlist, "tfind ", 1, &cmdlist);
2748
2749 add_cmd ("outside", class_trace, trace_find_outside_command,
2750 "Select a trace frame whose PC is outside the given \
2751 range.\nUsage: tfind outside addr1, addr2",
2752 &tfindlist);
2753
2754 add_cmd ("range", class_trace, trace_find_range_command,
2755 "Select a trace frame whose PC is in the given range.\n\
2756 Usage: tfind range addr1,addr2",
2757 &tfindlist);
2758
2759 add_cmd ("line", class_trace, trace_find_line_command,
2760 "Select a trace frame by source line.\n\
2761 Argument can be a line number (with optional source file), \n\
2762 a function name, or '*' followed by an address.\n\
2763 Default argument is 'the next source line that was traced'.",
2764 &tfindlist);
2765
2766 add_cmd ("tracepoint", class_trace, trace_find_tracepoint_command,
2767 "Select a trace frame by tracepoint number.\n\
2768 Default is the tracepoint for the current trace frame.",
2769 &tfindlist);
2770
2771 add_cmd ("pc", class_trace, trace_find_pc_command,
2772 "Select a trace frame by PC.\n\
2773 Default is the current PC, or the PC of the current trace frame.",
2774 &tfindlist);
2775
2776 add_cmd ("end", class_trace, trace_find_end_command,
2777 "Synonym for 'none'.\n\
2778 De-select any trace frame and resume 'live' debugging.",
2779 &tfindlist);
2780
2781 add_cmd ("none", class_trace, trace_find_none_command,
2782 "De-select any trace frame and resume 'live' debugging.",
2783 &tfindlist);
2784
2785 add_cmd ("start", class_trace, trace_find_start_command,
2786 "Select the first trace frame in the trace buffer.",
2787 &tfindlist);
2788
2789 add_com ("tstatus", class_trace, trace_status_command,
2790 "Display the status of the current trace data collection.");
2791
2792 add_com ("tstop", class_trace, trace_stop_command,
2793 "Stop trace data collection.");
2794
2795 add_com ("tstart", class_trace, trace_start_command,
2796 "Start trace data collection.");
2797
2798 add_com ("passcount", class_trace, trace_pass_command,
2799 "Set the passcount for a tracepoint.\n\
2800 The trace will end when the tracepoint has been passed 'count' times.\n\
2801 Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
2802 if TPNUM is omitted, passcount refers to the last tracepoint defined.");
2803
2804 add_com ("end", class_trace, end_actions_pseudocommand,
2805 "Ends a list of commands or actions.\n\
2806 Several GDB commands allow you to enter a list of commands or actions.\n\
2807 Entering \"end\" on a line by itself is the normal way to terminate\n\
2808 such a list.\n\n\
2809 Note: the \"end\" command cannot be used at the gdb prompt.");
2810
2811 add_com ("while-stepping", class_trace, while_stepping_pseudocommand,
2812 "Specify single-stepping behavior at a tracepoint.\n\
2813 Argument is number of instructions to trace in single-step mode\n\
2814 following the tracepoint. This command is normally followed by\n\
2815 one or more \"collect\" commands, to specify what to collect\n\
2816 while single-stepping.\n\n\
2817 Note: this command can only be used in a tracepoint \"actions\" list.");
2818
2819 add_com_alias ("ws", "while-stepping", class_alias, 0);
2820 add_com_alias ("stepping", "while-stepping", class_alias, 0);
2821
2822 add_com ("collect", class_trace, collect_pseudocommand,
2823 "Specify one or more data items to be collected at a tracepoint.\n\
2824 Accepts a comma-separated list of (one or more) expressions. GDB will\n\
2825 collect all data (variables, registers) referenced by that expression.\n\
2826 Also accepts the following special arguments:\n\
2827 $regs -- all registers.\n\
2828 $args -- all function arguments.\n\
2829 $locals -- all variables local to the block/function scope.\n\
2830 Note: this command can only be used in a tracepoint \"actions\" list.");
2831
2832 add_com ("actions", class_trace, trace_actions_command,
2833 "Specify the actions to be taken at a tracepoint.\n\
2834 Tracepoint actions may include collecting of specified data, \n\
2835 single-stepping, or enabling/disabling other tracepoints, \n\
2836 depending on target's capabilities.");
2837
2838 add_cmd ("tracepoints", class_trace, delete_trace_command,
2839 "Delete specified tracepoints.\n\
2840 Arguments are tracepoint numbers, separated by spaces.\n\
2841 No argument means delete all tracepoints.",
2842 &deletelist);
2843
2844 add_cmd ("tracepoints", class_trace, disable_trace_command,
2845 "Disable specified tracepoints.\n\
2846 Arguments are tracepoint numbers, separated by spaces.\n\
2847 No argument means disable all tracepoints.",
2848 &disablelist);
2849
2850 add_cmd ("tracepoints", class_trace, enable_trace_command,
2851 "Enable specified tracepoints.\n\
2852 Arguments are tracepoint numbers, separated by spaces.\n\
2853 No argument means enable all tracepoints.",
2854 &enablelist);
2855
2856 add_com ("trace", class_trace, trace_command,
2857 "Set a tracepoint at a specified line or function or address.\n\
2858 Argument may be a line number, function name, or '*' plus an address.\n\
2859 For a line number or function, trace at the start of its code.\n\
2860 If an address is specified, trace at that exact address.\n\n\
2861 Do \"help tracepoints\" for info on other tracepoint commands.");
2862
2863 add_com_alias ("tp", "trace", class_alias, 0);
2864 add_com_alias ("tr", "trace", class_alias, 1);
2865 add_com_alias ("tra", "trace", class_alias, 1);
2866 add_com_alias ("trac", "trace", class_alias, 1);
2867 }