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