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