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