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