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