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