Re-indent INIT_ARRAY.
[deliverable/binutils-gdb.git] / gdb / tracepoint.c
CommitLineData
c906108c 1/* Tracing functionality for remote targets in custom GDB protocol
9f60d481 2
6aba47ca 3 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
4c38e0a4 4 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
c906108c 5
c5aa993b 6 This file is part of GDB.
c906108c 7
c5aa993b
JM
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
c5aa993b 11 (at your option) any later version.
c906108c 12
c5aa993b
JM
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
c906108c 17
c5aa993b 18 You should have received a copy of the GNU General Public License
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
20
21#include "defs.h"
5af949e3 22#include "arch-utils.h"
c906108c
SS
23#include "symtab.h"
24#include "frame.h"
c906108c
SS
25#include "gdbtypes.h"
26#include "expression.h"
27#include "gdbcmd.h"
28#include "value.h"
29#include "target.h"
30#include "language.h"
31#include "gdb_string.h"
104c1213 32#include "inferior.h"
1042e4c0 33#include "breakpoint.h"
104c1213 34#include "tracepoint.h"
c5f0f3d0 35#include "linespec.h"
4e052eda 36#include "regcache.h"
c94fdfd0 37#include "completer.h"
fe898f56 38#include "block.h"
de4f826b 39#include "dictionary.h"
383f836e 40#include "observer.h"
029a67e4 41#include "user-regs.h"
79a45b7d 42#include "valprint.h"
41575630 43#include "gdbcore.h"
768a979c 44#include "objfiles.h"
35b1e5cc 45#include "filenames.h"
00bf0b85 46#include "gdbthread.h"
c906108c
SS
47
48#include "ax.h"
49#include "ax-gdb.h"
50
51/* readline include files */
dbda9972
AC
52#include "readline/readline.h"
53#include "readline/history.h"
c906108c
SS
54
55/* readline defines this. */
56#undef savestring
57
58#ifdef HAVE_UNISTD_H
59#include <unistd.h>
60#endif
61
00bf0b85
SS
62#ifndef O_LARGEFILE
63#define O_LARGEFILE 0
64#endif
65
66extern int hex2bin (const char *hex, gdb_byte *bin, int count);
67extern int bin2hex (const gdb_byte *bin, char *hex, int count);
68
d5551862
SS
69extern void stop_tracing ();
70
d183932d
MS
71/* Maximum length of an agent aexpression.
72 This accounts for the fact that packets are limited to 400 bytes
c906108c
SS
73 (which includes everything -- including the checksum), and assumes
74 the worst case of maximum length for each of the pieces of a
75 continuation packet.
c5aa993b 76
c906108c
SS
77 NOTE: expressions get mem2hex'ed otherwise this would be twice as
78 large. (400 - 31)/2 == 184 */
79#define MAX_AGENT_EXPR_LEN 184
80
98c5b216
TT
81/* A hook used to notify the UI of tracepoint operations. */
82
83void (*deprecated_trace_find_hook) (char *arg, int from_tty);
84void (*deprecated_trace_start_stop_hook) (int start, int from_tty);
c906108c 85
9a4105ab
AC
86extern void (*deprecated_readline_begin_hook) (char *, ...);
87extern char *(*deprecated_readline_hook) (char *);
88extern void (*deprecated_readline_end_hook) (void);
c906108c 89
104c1213
JM
90/* GDB commands implemented in other modules:
91 */
92
a14ed312 93extern void output_command (char *, int);
104c1213 94
c906108c
SS
95/*
96 Tracepoint.c:
97
98 This module defines the following debugger commands:
99 trace : set a tracepoint on a function, line, or address.
100 info trace : list all debugger-defined tracepoints.
101 delete trace : delete one or more tracepoints.
102 enable trace : enable one or more tracepoints.
103 disable trace : disable one or more tracepoints.
104 actions : specify actions to be taken at a tracepoint.
105 passcount : specify a pass count for a tracepoint.
106 tstart : start a trace experiment.
107 tstop : stop a trace experiment.
108 tstatus : query the status of a trace experiment.
109 tfind : find a trace frame in the trace buffer.
110 tdump : print everything collected at the current tracepoint.
111 save-tracepoints : write tracepoint setup into a file.
112
113 This module defines the following user-visible debugger variables:
114 $trace_frame : sequence number of trace frame currently being debugged.
115 $trace_line : source line of trace frame currently being debugged.
116 $trace_file : source file of trace frame currently being debugged.
117 $tracepoint : tracepoint number of trace frame currently being debugged.
c5aa993b 118 */
c906108c
SS
119
120
121/* ======= Important global variables: ======= */
122
f61e138d
SS
123/* The list of all trace state variables. We don't retain pointers to
124 any of these for any reason - API is by name or number only - so it
125 works to have a vector of objects. */
126
127typedef struct trace_state_variable tsv_s;
128DEF_VEC_O(tsv_s);
129
130static VEC(tsv_s) *tvariables;
131
132/* The next integer to assign to a variable. */
133
134static int next_tsv_number = 1;
135
c906108c
SS
136/* Number of last traceframe collected. */
137static int traceframe_number;
138
139/* Tracepoint for last traceframe collected. */
140static int tracepoint_number;
141
142/* Symbol for function for last traceframe collected */
143static struct symbol *traceframe_fun;
144
145/* Symtab and line for last traceframe collected */
146static struct symtab_and_line traceframe_sal;
147
148/* Tracing command lists */
149static struct cmd_list_element *tfindlist;
150
236f1d4d 151/* List of expressions to collect by default at each tracepoint hit. */
35b1e5cc 152char *default_collect = "";
236f1d4d 153
d5551862
SS
154static int disconnected_tracing;
155
c906108c 156/* ======= Important command functions: ======= */
a14ed312
KB
157static void trace_actions_command (char *, int);
158static void trace_start_command (char *, int);
159static void trace_stop_command (char *, int);
160static void trace_status_command (char *, int);
161static void trace_find_command (char *, int);
162static void trace_find_pc_command (char *, int);
163static void trace_find_tracepoint_command (char *, int);
164static void trace_find_line_command (char *, int);
165static void trace_find_range_command (char *, int);
166static void trace_find_outside_command (char *, int);
a14ed312 167static void trace_dump_command (char *, int);
c906108c
SS
168
169/* support routines */
c906108c
SS
170
171struct collection_list;
a14ed312 172static void add_aexpr (struct collection_list *, struct agent_expr *);
47b667de 173static char *mem2hex (gdb_byte *, char *, int);
a14ed312
KB
174static void add_register (struct collection_list *collection,
175 unsigned int regno);
1042e4c0 176static struct cleanup *make_cleanup_free_actions (struct breakpoint *t);
392a587b 177
d5551862
SS
178extern void send_disconnected_tracing_value (int value);
179
00bf0b85
SS
180static void free_uploaded_tps (struct uploaded_tp **utpp);
181static void free_uploaded_tsvs (struct uploaded_tsv **utsvp);
182
183
a14ed312 184extern void _initialize_tracepoint (void);
c906108c 185
00bf0b85
SS
186static struct trace_status trace_status;
187
188char *stop_reason_names[] = {
189 "tunknown",
190 "tnotrun",
191 "tstop",
192 "tfull",
193 "tdisconnected",
194 "tpasscount"
195};
196
197struct trace_status *
198current_trace_status ()
199{
200 return &trace_status;
201}
202
c906108c
SS
203/* Set traceframe number to NUM. */
204static void
fba45db2 205set_traceframe_num (int num)
c906108c
SS
206{
207 traceframe_number = num;
4fa62494 208 set_internalvar_integer (lookup_internalvar ("trace_frame"), num);
c906108c
SS
209}
210
211/* Set tracepoint number to NUM. */
212static void
fba45db2 213set_tracepoint_num (int num)
c906108c
SS
214{
215 tracepoint_number = num;
4fa62494 216 set_internalvar_integer (lookup_internalvar ("tracepoint"), num);
c906108c
SS
217}
218
219/* Set externally visible debug variables for querying/printing
220 the traceframe context (line, function, file) */
221
222static void
fb14de7b 223set_traceframe_context (struct frame_info *trace_frame)
c906108c 224{
fb14de7b
UW
225 CORE_ADDR trace_pc;
226
fb14de7b 227 if (trace_frame == NULL) /* Cease debugging any trace buffers. */
c906108c
SS
228 {
229 traceframe_fun = 0;
230 traceframe_sal.pc = traceframe_sal.line = 0;
231 traceframe_sal.symtab = NULL;
4fa62494
UW
232 clear_internalvar (lookup_internalvar ("trace_func"));
233 clear_internalvar (lookup_internalvar ("trace_file"));
234 set_internalvar_integer (lookup_internalvar ("trace_line"), -1);
c906108c
SS
235 return;
236 }
237
d183932d 238 /* Save as globals for internal use. */
fb14de7b 239 trace_pc = get_frame_pc (trace_frame);
c906108c
SS
240 traceframe_sal = find_pc_line (trace_pc, 0);
241 traceframe_fun = find_pc_function (trace_pc);
242
d183932d
MS
243 /* Save linenumber as "$trace_line", a debugger variable visible to
244 users. */
4fa62494
UW
245 set_internalvar_integer (lookup_internalvar ("trace_line"),
246 traceframe_sal.line);
c906108c 247
d183932d
MS
248 /* Save func name as "$trace_func", a debugger variable visible to
249 users. */
4fa62494
UW
250 if (traceframe_fun == NULL
251 || SYMBOL_LINKAGE_NAME (traceframe_fun) == NULL)
252 clear_internalvar (lookup_internalvar ("trace_func"));
c906108c 253 else
78267919
UW
254 set_internalvar_string (lookup_internalvar ("trace_func"),
255 SYMBOL_LINKAGE_NAME (traceframe_fun));
c906108c 256
d183932d
MS
257 /* Save file name as "$trace_file", a debugger variable visible to
258 users. */
4fa62494
UW
259 if (traceframe_sal.symtab == NULL
260 || traceframe_sal.symtab->filename == NULL)
261 clear_internalvar (lookup_internalvar ("trace_file"));
c906108c 262 else
78267919
UW
263 set_internalvar_string (lookup_internalvar ("trace_file"),
264 traceframe_sal.symtab->filename);
c906108c
SS
265}
266
f61e138d
SS
267/* Create a new trace state variable with the given name. */
268
269struct trace_state_variable *
270create_trace_state_variable (const char *name)
271{
272 struct trace_state_variable tsv;
273
274 memset (&tsv, 0, sizeof (tsv));
275 tsv.name = name;
276 tsv.number = next_tsv_number++;
277 return VEC_safe_push (tsv_s, tvariables, &tsv);
278}
279
280/* Look for a trace state variable of the given name. */
281
282struct trace_state_variable *
283find_trace_state_variable (const char *name)
284{
285 struct trace_state_variable *tsv;
286 int ix;
287
288 for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
289 if (strcmp (name, tsv->name) == 0)
290 return tsv;
291
292 return NULL;
293}
294
295void
296delete_trace_state_variable (const char *name)
297{
298 struct trace_state_variable *tsv;
299 int ix;
300
301 for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
302 if (strcmp (name, tsv->name) == 0)
303 {
304 VEC_unordered_remove (tsv_s, tvariables, ix);
305 return;
306 }
307
308 warning (_("No trace variable named \"$%s\", not deleting"), name);
309}
310
311/* The 'tvariable' command collects a name and optional expression to
312 evaluate into an initial value. */
313
314void
315trace_variable_command (char *args, int from_tty)
316{
317 struct expression *expr;
318 struct cleanup *old_chain;
319 struct internalvar *intvar = NULL;
320 LONGEST initval = 0;
321 struct trace_state_variable *tsv;
322
323 if (!args || !*args)
324 error_no_arg (_("trace state variable name"));
325
326 /* All the possible valid arguments are expressions. */
327 expr = parse_expression (args);
328 old_chain = make_cleanup (free_current_contents, &expr);
329
330 if (expr->nelts == 0)
331 error (_("No expression?"));
332
333 /* Only allow two syntaxes; "$name" and "$name=value". */
334 if (expr->elts[0].opcode == OP_INTERNALVAR)
335 {
336 intvar = expr->elts[1].internalvar;
337 }
338 else if (expr->elts[0].opcode == BINOP_ASSIGN
339 && expr->elts[1].opcode == OP_INTERNALVAR)
340 {
341 intvar = expr->elts[2].internalvar;
342 initval = value_as_long (evaluate_subexpression_type (expr, 4));
343 }
344 else
345 error (_("Syntax must be $NAME [ = EXPR ]"));
346
347 if (!intvar)
348 error (_("No name given"));
349
350 if (strlen (internalvar_name (intvar)) <= 0)
351 error (_("Must supply a non-empty variable name"));
352
353 /* If the variable already exists, just change its initial value. */
354 tsv = find_trace_state_variable (internalvar_name (intvar));
355 if (tsv)
356 {
357 tsv->initial_value = initval;
358 printf_filtered (_("Trace state variable $%s now has initial value %s.\n"),
359 tsv->name, plongest (tsv->initial_value));
360 return;
361 }
362
363 /* Create a new variable. */
364 tsv = create_trace_state_variable (internalvar_name (intvar));
365 tsv->initial_value = initval;
366
367 printf_filtered (_("Trace state variable $%s created, with initial value %s.\n"),
368 tsv->name, plongest (tsv->initial_value));
369
370 do_cleanups (old_chain);
371}
372
373void
374delete_trace_variable_command (char *args, int from_tty)
375{
376 int i, ix;
377 char **argv;
378 struct cleanup *back_to;
379 struct trace_state_variable *tsv;
380
381 if (args == NULL)
382 {
383 if (query (_("Delete all trace state variables? ")))
384 VEC_free (tsv_s, tvariables);
385 dont_repeat ();
386 return;
387 }
388
389 argv = gdb_buildargv (args);
390 back_to = make_cleanup_freeargv (argv);
391
392 for (i = 0; argv[i] != NULL; i++)
393 {
394 if (*argv[i] == '$')
395 delete_trace_state_variable (argv[i] + 1);
396 else
397 warning (_("Name \"%s\" not prefixed with '$', ignoring"), argv[i]);
398 }
399
400 do_cleanups (back_to);
401
402 dont_repeat ();
403}
404
405/* List all the trace state variables. */
406
407static void
408tvariables_info (char *args, int from_tty)
409{
410 struct trace_state_variable *tsv;
411 int ix;
412 char *reply;
413 ULONGEST tval;
414
f61e138d
SS
415 if (VEC_length (tsv_s, tvariables) == 0)
416 {
417 printf_filtered (_("No trace state variables.\n"));
418 return;
419 }
420
35b1e5cc
SS
421 /* Try to acquire values from the target. */
422 for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
423 tsv->value_known = target_get_trace_state_variable_value (tsv->number,
424 &(tsv->value));
425
f61e138d
SS
426 printf_filtered (_("Name\t\t Initial\tCurrent\n"));
427
428 for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
429 {
430 printf_filtered ("$%s", tsv->name);
431 print_spaces_filtered (17 - strlen (tsv->name), gdb_stdout);
432 printf_filtered ("%s ", plongest (tsv->initial_value));
433 print_spaces_filtered (11 - strlen (plongest (tsv->initial_value)), gdb_stdout);
434 if (tsv->value_known)
435 printf_filtered (" %s", plongest (tsv->value));
00bf0b85 436 else if (current_trace_status ()->running || traceframe_number >= 0)
f61e138d
SS
437 /* The value is/was defined, but we don't have it. */
438 printf_filtered (_(" <unknown>"));
439 else
440 /* It is not meaningful to ask about the value. */
441 printf_filtered (_(" <undefined>"));
442 printf_filtered ("\n");
443 }
444}
445
c906108c
SS
446/* ACTIONS functions: */
447
448/* Prototypes for action-parsing utility commands */
1042e4c0 449static void read_actions (struct breakpoint *);
c906108c
SS
450
451/* The three functions:
c5aa993b
JM
452 collect_pseudocommand,
453 while_stepping_pseudocommand, and
454 end_actions_pseudocommand
c906108c
SS
455 are placeholders for "commands" that are actually ONLY to be used
456 within a tracepoint action list. If the actual function is ever called,
457 it means that somebody issued the "command" at the top level,
458 which is always an error. */
459
1042e4c0 460void
fba45db2 461end_actions_pseudocommand (char *args, int from_tty)
c906108c 462{
8a3fe4f8 463 error (_("This command cannot be used at the top level."));
c906108c
SS
464}
465
1042e4c0 466void
fba45db2 467while_stepping_pseudocommand (char *args, int from_tty)
c906108c 468{
8a3fe4f8 469 error (_("This command can only be used in a tracepoint actions list."));
c906108c
SS
470}
471
472static void
fba45db2 473collect_pseudocommand (char *args, int from_tty)
c906108c 474{
8a3fe4f8 475 error (_("This command can only be used in a tracepoint actions list."));
c906108c
SS
476}
477
6da95a67
SS
478static void
479teval_pseudocommand (char *args, int from_tty)
480{
481 error (_("This command can only be used in a tracepoint actions list."));
482}
483
c906108c
SS
484/* Enter a list of actions for a tracepoint. */
485static void
fba45db2 486trace_actions_command (char *args, int from_tty)
c906108c 487{
1042e4c0 488 struct breakpoint *t;
c906108c
SS
489 char tmpbuf[128];
490 char *end_msg = "End with a line saying just \"end\".";
491
c2d11a7d 492 t = get_tracepoint_by_number (&args, 0, 1);
7a292a7a 493 if (t)
c906108c
SS
494 {
495 sprintf (tmpbuf, "Enter actions for tracepoint %d, one per line.",
496 t->number);
497
498 if (from_tty)
499 {
9a4105ab
AC
500 if (deprecated_readline_begin_hook)
501 (*deprecated_readline_begin_hook) ("%s %s\n", tmpbuf, end_msg);
c906108c
SS
502 else if (input_from_terminal_p ())
503 printf_filtered ("%s\n%s\n", tmpbuf, end_msg);
504 }
505
506 free_actions (t);
507 t->step_count = 0; /* read_actions may set this */
508 read_actions (t);
509
9a4105ab
AC
510 if (deprecated_readline_end_hook)
511 (*deprecated_readline_end_hook) ();
c906108c
SS
512 /* tracepoints_changed () */
513 }
5c44784c 514 /* else just return */
c906108c
SS
515}
516
517/* worker function */
518static void
1042e4c0 519read_actions (struct breakpoint *t)
c906108c
SS
520{
521 char *line;
522 char *prompt1 = "> ", *prompt2 = " > ";
523 char *prompt = prompt1;
524 enum actionline_type linetype;
525 extern FILE *instream;
526 struct action_line *next = NULL, *temp;
527 struct cleanup *old_chain;
528
529 /* Control-C quits instantly if typed while in this loop
530 since it should not wait until the user types a newline. */
531 immediate_quit++;
1a6fae3c
MK
532 /* FIXME: kettenis/20010823: Something is wrong here. In this file
533 STOP_SIGNAL is never defined. So this code has been left out, at
534 least for quite a while now. Replacing STOP_SIGNAL with SIGTSTP
535 leads to compilation failures since the variable job_control
536 isn't declared. Leave this alone for now. */
c906108c
SS
537#ifdef STOP_SIGNAL
538 if (job_control)
362646f5 539 signal (STOP_SIGNAL, handle_stop_sig);
c906108c 540#endif
74b7792f 541 old_chain = make_cleanup_free_actions (t);
c906108c
SS
542 while (1)
543 {
d183932d
MS
544 /* Make sure that all output has been output. Some machines may
545 let you get away with leaving out some of the gdb_flush, but
546 not all. */
c906108c
SS
547 wrap_here ("");
548 gdb_flush (gdb_stdout);
549 gdb_flush (gdb_stderr);
550
9a4105ab
AC
551 if (deprecated_readline_hook && instream == NULL)
552 line = (*deprecated_readline_hook) (prompt);
c906108c
SS
553 else if (instream == stdin && ISATTY (instream))
554 {
b4f5539f 555 line = gdb_readline_wrapper (prompt);
c5aa993b 556 if (line && *line) /* add it to command history */
c906108c
SS
557 add_history (line);
558 }
559 else
560 line = gdb_readline (0);
561
549678da 562 if (!line)
d844e34b
JB
563 {
564 line = xstrdup ("end");
565 printf_filtered ("end\n");
566 }
549678da 567
c906108c
SS
568 linetype = validate_actionline (&line, t);
569 if (linetype == BADLINE)
c5aa993b 570 continue; /* already warned -- collect another line */
c906108c
SS
571
572 temp = xmalloc (sizeof (struct action_line));
573 temp->next = NULL;
574 temp->action = line;
575
576 if (next == NULL) /* first action for this tracepoint? */
577 t->actions = next = temp;
578 else
579 {
580 next->next = temp;
581 next = temp;
582 }
583
584 if (linetype == STEPPING) /* begin "while-stepping" */
7a292a7a
SS
585 {
586 if (prompt == prompt2)
587 {
8a3fe4f8 588 warning (_("Already processing 'while-stepping'"));
7a292a7a
SS
589 continue;
590 }
591 else
592 prompt = prompt2; /* change prompt for stepping actions */
593 }
c906108c 594 else if (linetype == END)
7a292a7a
SS
595 {
596 if (prompt == prompt2)
597 {
598 prompt = prompt1; /* end of single-stepping actions */
599 }
600 else
c5aa993b 601 { /* end of actions */
7a292a7a
SS
602 if (t->actions->next == NULL)
603 {
d183932d
MS
604 /* An "end" all by itself with no other actions
605 means this tracepoint has no actions.
606 Discard empty list. */
7a292a7a
SS
607 free_actions (t);
608 }
609 break;
610 }
611 }
c906108c
SS
612 }
613#ifdef STOP_SIGNAL
614 if (job_control)
615 signal (STOP_SIGNAL, SIG_DFL);
616#endif
8edbea78 617 immediate_quit--;
c906108c
SS
618 discard_cleanups (old_chain);
619}
620
621/* worker function */
622enum actionline_type
1042e4c0 623validate_actionline (char **line, struct breakpoint *t)
c906108c
SS
624{
625 struct cmd_list_element *c;
626 struct expression *exp = NULL;
c906108c 627 struct cleanup *old_chain = NULL;
9355b391
SS
628 char *p, *tmp_p;
629 struct bp_location *loc;
c906108c 630
15255275
MS
631 /* if EOF is typed, *line is NULL */
632 if (*line == NULL)
633 return END;
634
104c1213 635 for (p = *line; isspace ((int) *p);)
c906108c
SS
636 p++;
637
d183932d
MS
638 /* Symbol lookup etc. */
639 if (*p == '\0') /* empty line: just prompt for another line. */
c906108c
SS
640 return BADLINE;
641
c5aa993b 642 if (*p == '#') /* comment line */
c906108c
SS
643 return GENERIC;
644
645 c = lookup_cmd (&p, cmdlist, "", -1, 1);
646 if (c == 0)
647 {
8a3fe4f8 648 warning (_("'%s' is not an action that I know, or is ambiguous."),
d183932d 649 p);
c906108c
SS
650 return BADLINE;
651 }
c5aa993b 652
bbaca940 653 if (cmd_cfunc_eq (c, collect_pseudocommand))
c906108c
SS
654 {
655 struct agent_expr *aexpr;
656 struct agent_reqs areqs;
657
c5aa993b
JM
658 do
659 { /* repeat over a comma-separated list */
660 QUIT; /* allow user to bail out with ^C */
104c1213 661 while (isspace ((int) *p))
c5aa993b 662 p++;
c906108c 663
c5aa993b
JM
664 if (*p == '$') /* look for special pseudo-symbols */
665 {
c5aa993b
JM
666 if ((0 == strncasecmp ("reg", p + 1, 3)) ||
667 (0 == strncasecmp ("arg", p + 1, 3)) ||
668 (0 == strncasecmp ("loc", p + 1, 3)))
669 {
670 p = strchr (p, ',');
671 continue;
672 }
d183932d 673 /* else fall thru, treat p as an expression and parse it! */
c5aa993b 674 }
9355b391
SS
675 tmp_p = p;
676 for (loc = t->loc; loc; loc = loc->next)
c5aa993b 677 {
9355b391
SS
678 p = tmp_p;
679 exp = parse_exp_1 (&p, block_for_pc (loc->address), 1);
680 old_chain = make_cleanup (free_current_contents, &exp);
681
682 if (exp->elts[0].opcode == OP_VAR_VALUE)
c5aa993b 683 {
9355b391
SS
684 if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_CONST)
685 {
686 warning (_("constant %s (value %ld) will not be collected."),
687 SYMBOL_PRINT_NAME (exp->elts[2].symbol),
688 SYMBOL_VALUE (exp->elts[2].symbol));
689 return BADLINE;
690 }
691 else if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_OPTIMIZED_OUT)
692 {
693 warning (_("%s is optimized away and cannot be collected."),
694 SYMBOL_PRINT_NAME (exp->elts[2].symbol));
695 return BADLINE;
696 }
c5aa993b 697 }
c906108c 698
9355b391
SS
699 /* We have something to collect, make sure that the expr to
700 bytecode translator can handle it and that it's not too
701 long. */
702 aexpr = gen_trace_for_expr (loc->address, exp);
703 make_cleanup_free_agent_expr (aexpr);
c906108c 704
9355b391
SS
705 if (aexpr->len > MAX_AGENT_EXPR_LEN)
706 error (_("expression too complicated, try simplifying"));
c906108c 707
9355b391
SS
708 ax_reqs (aexpr, &areqs);
709 (void) make_cleanup (xfree, areqs.reg_mask);
c906108c 710
9355b391
SS
711 if (areqs.flaw != agent_flaw_none)
712 error (_("malformed expression"));
c906108c 713
9355b391
SS
714 if (areqs.min_height < 0)
715 error (_("gdb: Internal error: expression has min height < 0"));
c906108c 716
9355b391
SS
717 if (areqs.max_height > 20)
718 error (_("expression too complicated, try simplifying"));
c906108c 719
9355b391
SS
720 do_cleanups (old_chain);
721 }
c5aa993b
JM
722 }
723 while (p && *p++ == ',');
c906108c
SS
724 return GENERIC;
725 }
6da95a67
SS
726 else if (cmd_cfunc_eq (c, teval_pseudocommand))
727 {
728 struct agent_expr *aexpr;
729
730 do
731 { /* repeat over a comma-separated list */
732 QUIT; /* allow user to bail out with ^C */
733 while (isspace ((int) *p))
734 p++;
735
9355b391
SS
736 tmp_p = p;
737 for (loc = t->loc; loc; loc = loc->next)
738 {
739 p = tmp_p;
740 /* Only expressions are allowed for this action. */
741 exp = parse_exp_1 (&p, block_for_pc (loc->address), 1);
742 old_chain = make_cleanup (free_current_contents, &exp);
6da95a67 743
9355b391
SS
744 /* We have something to evaluate, make sure that the expr to
745 bytecode translator can handle it and that it's not too
746 long. */
747 aexpr = gen_eval_for_expr (loc->address, exp);
748 make_cleanup_free_agent_expr (aexpr);
6da95a67 749
9355b391
SS
750 if (aexpr->len > MAX_AGENT_EXPR_LEN)
751 error (_("expression too complicated, try simplifying"));
6da95a67 752
9355b391
SS
753 do_cleanups (old_chain);
754 }
6da95a67
SS
755 }
756 while (p && *p++ == ',');
757 return GENERIC;
758 }
bbaca940 759 else if (cmd_cfunc_eq (c, while_stepping_pseudocommand))
c906108c 760 {
c5aa993b 761 char *steparg; /* in case warning is necessary */
c906108c 762
104c1213 763 while (isspace ((int) *p))
c906108c
SS
764 p++;
765 steparg = p;
766
767 if (*p == '\0' ||
768 (t->step_count = strtol (p, &p, 0)) == 0)
769 {
8a3fe4f8 770 warning (_("'%s': bad step-count; command ignored."), *line);
c906108c
SS
771 return BADLINE;
772 }
773 return STEPPING;
774 }
bbaca940 775 else if (cmd_cfunc_eq (c, end_actions_pseudocommand))
c906108c
SS
776 return END;
777 else
778 {
8a3fe4f8 779 warning (_("'%s' is not a supported tracepoint action."), *line);
c906108c
SS
780 return BADLINE;
781 }
782}
783
784/* worker function */
c5aa993b 785void
1042e4c0 786free_actions (struct breakpoint *t)
c906108c
SS
787{
788 struct action_line *line, *next;
789
790 for (line = t->actions; line; line = next)
791 {
792 next = line->next;
c5aa993b 793 if (line->action)
b8c9b27d
KB
794 xfree (line->action);
795 xfree (line);
c906108c
SS
796 }
797 t->actions = NULL;
798}
799
74b7792f
AC
800static void
801do_free_actions_cleanup (void *t)
802{
803 free_actions (t);
804}
805
806static struct cleanup *
1042e4c0 807make_cleanup_free_actions (struct breakpoint *t)
74b7792f
AC
808{
809 return make_cleanup (do_free_actions_cleanup, t);
810}
811
f50e79a4
JB
812enum {
813 memrange_absolute = -1
814};
815
c5aa993b
JM
816struct memrange
817{
f50e79a4
JB
818 int type; /* memrange_absolute for absolute memory range,
819 else basereg number */
c906108c
SS
820 bfd_signed_vma start;
821 bfd_signed_vma end;
822};
823
c5aa993b
JM
824struct collection_list
825 {
549678da 826 unsigned char regs_mask[32]; /* room for up to 256 regs */
c5aa993b
JM
827 long listsize;
828 long next_memrange;
829 struct memrange *list;
830 long aexpr_listsize; /* size of array pointed to by expr_list elt */
831 long next_aexpr_elt;
832 struct agent_expr **aexpr_list;
833
834 }
835tracepoint_list, stepping_list;
c906108c
SS
836
837/* MEMRANGE functions: */
838
a14ed312 839static int memrange_cmp (const void *, const void *);
c906108c
SS
840
841/* compare memranges for qsort */
842static int
fba45db2 843memrange_cmp (const void *va, const void *vb)
c906108c
SS
844{
845 const struct memrange *a = va, *b = vb;
846
847 if (a->type < b->type)
848 return -1;
849 if (a->type > b->type)
c5aa993b 850 return 1;
f50e79a4 851 if (a->type == memrange_absolute)
c906108c 852 {
c5aa993b
JM
853 if ((bfd_vma) a->start < (bfd_vma) b->start)
854 return -1;
855 if ((bfd_vma) a->start > (bfd_vma) b->start)
856 return 1;
c906108c
SS
857 }
858 else
859 {
c5aa993b 860 if (a->start < b->start)
c906108c 861 return -1;
c5aa993b
JM
862 if (a->start > b->start)
863 return 1;
c906108c
SS
864 }
865 return 0;
866}
867
d183932d 868/* Sort the memrange list using qsort, and merge adjacent memranges. */
c906108c 869static void
fba45db2 870memrange_sortmerge (struct collection_list *memranges)
c906108c
SS
871{
872 int a, b;
873
c5aa993b 874 qsort (memranges->list, memranges->next_memrange,
c906108c
SS
875 sizeof (struct memrange), memrange_cmp);
876 if (memranges->next_memrange > 0)
877 {
878 for (a = 0, b = 1; b < memranges->next_memrange; b++)
879 {
880 if (memranges->list[a].type == memranges->list[b].type &&
c5aa993b 881 memranges->list[b].start - memranges->list[a].end <=
0c92afe8 882 MAX_REGISTER_SIZE)
c906108c
SS
883 {
884 /* memrange b starts before memrange a ends; merge them. */
885 if (memranges->list[b].end > memranges->list[a].end)
886 memranges->list[a].end = memranges->list[b].end;
887 continue; /* next b, same a */
888 }
889 a++; /* next a */
890 if (a != b)
c5aa993b 891 memcpy (&memranges->list[a], &memranges->list[b],
c906108c
SS
892 sizeof (struct memrange));
893 }
894 memranges->next_memrange = a + 1;
895 }
896}
897
d183932d 898/* Add a register to a collection list. */
392a587b 899static void
fba45db2 900add_register (struct collection_list *collection, unsigned int regno)
c906108c
SS
901{
902 if (info_verbose)
903 printf_filtered ("collect register %d\n", regno);
27e06d3e 904 if (regno >= (8 * sizeof (collection->regs_mask)))
8a3fe4f8 905 error (_("Internal: register number %d too large for tracepoint"),
c906108c 906 regno);
c5aa993b 907 collection->regs_mask[regno / 8] |= 1 << (regno % 8);
c906108c
SS
908}
909
910/* Add a memrange to a collection list */
911static void
d183932d
MS
912add_memrange (struct collection_list *memranges,
913 int type, bfd_signed_vma base,
fba45db2 914 unsigned long len)
c906108c
SS
915{
916 if (info_verbose)
104c1213
JM
917 {
918 printf_filtered ("(%d,", type);
919 printf_vma (base);
920 printf_filtered (",%ld)\n", len);
921 }
922
f50e79a4 923 /* type: memrange_absolute == memory, other n == basereg */
c5aa993b 924 memranges->list[memranges->next_memrange].type = type;
d183932d 925 /* base: addr if memory, offset if reg relative. */
c906108c
SS
926 memranges->list[memranges->next_memrange].start = base;
927 /* len: we actually save end (base + len) for convenience */
c5aa993b 928 memranges->list[memranges->next_memrange].end = base + len;
c906108c
SS
929 memranges->next_memrange++;
930 if (memranges->next_memrange >= memranges->listsize)
931 {
932 memranges->listsize *= 2;
c5aa993b 933 memranges->list = xrealloc (memranges->list,
c906108c
SS
934 memranges->listsize);
935 }
936
f50e79a4 937 if (type != memrange_absolute) /* Better collect the base register! */
c906108c
SS
938 add_register (memranges, type);
939}
940
d183932d 941/* Add a symbol to a collection list. */
c906108c 942static void
d183932d
MS
943collect_symbol (struct collection_list *collect,
944 struct symbol *sym,
a6d9a66e 945 struct gdbarch *gdbarch,
0936ad1d
SS
946 long frame_regno, long frame_offset,
947 CORE_ADDR scope)
c906108c 948{
c5aa993b 949 unsigned long len;
104c1213 950 unsigned int reg;
c906108c 951 bfd_signed_vma offset;
400c6af0 952 int treat_as_expr = 0;
c906108c 953
c5aa993b
JM
954 len = TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym)));
955 switch (SYMBOL_CLASS (sym))
956 {
957 default:
958 printf_filtered ("%s: don't know symbol class %d\n",
3567439c 959 SYMBOL_PRINT_NAME (sym),
d183932d 960 SYMBOL_CLASS (sym));
c5aa993b
JM
961 break;
962 case LOC_CONST:
104c1213 963 printf_filtered ("constant %s (value %ld) will not be collected.\n",
3567439c 964 SYMBOL_PRINT_NAME (sym), SYMBOL_VALUE (sym));
c5aa993b
JM
965 break;
966 case LOC_STATIC:
967 offset = SYMBOL_VALUE_ADDRESS (sym);
968 if (info_verbose)
104c1213
JM
969 {
970 char tmp[40];
971
972 sprintf_vma (tmp, offset);
973 printf_filtered ("LOC_STATIC %s: collect %ld bytes at %s.\n",
3567439c 974 SYMBOL_PRINT_NAME (sym), len,
d183932d 975 tmp /* address */);
104c1213 976 }
400c6af0
SS
977 /* A struct may be a C++ class with static fields, go to general
978 expression handling. */
979 if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT)
980 treat_as_expr = 1;
981 else
982 add_memrange (collect, memrange_absolute, offset, len);
c5aa993b
JM
983 break;
984 case LOC_REGISTER:
a6d9a66e 985 reg = SYMBOL_REGISTER_OPS (sym)->register_number (sym, gdbarch);
c5aa993b 986 if (info_verbose)
d183932d 987 printf_filtered ("LOC_REG[parm] %s: ",
3567439c 988 SYMBOL_PRINT_NAME (sym));
c5aa993b 989 add_register (collect, reg);
d183932d
MS
990 /* Check for doubles stored in two registers. */
991 /* FIXME: how about larger types stored in 3 or more regs? */
c5aa993b 992 if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FLT &&
a6d9a66e 993 len > register_size (gdbarch, reg))
c5aa993b
JM
994 add_register (collect, reg + 1);
995 break;
996 case LOC_REF_ARG:
997 printf_filtered ("Sorry, don't know how to do LOC_REF_ARG yet.\n");
998 printf_filtered (" (will not collect %s)\n",
3567439c 999 SYMBOL_PRINT_NAME (sym));
c5aa993b
JM
1000 break;
1001 case LOC_ARG:
1002 reg = frame_regno;
1003 offset = frame_offset + SYMBOL_VALUE (sym);
1004 if (info_verbose)
1005 {
104c1213 1006 printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset ",
3567439c 1007 SYMBOL_PRINT_NAME (sym), len);
104c1213
JM
1008 printf_vma (offset);
1009 printf_filtered (" from frame ptr reg %d\n", reg);
c5aa993b
JM
1010 }
1011 add_memrange (collect, reg, offset, len);
1012 break;
1013 case LOC_REGPARM_ADDR:
1014 reg = SYMBOL_VALUE (sym);
1015 offset = 0;
1016 if (info_verbose)
1017 {
104c1213 1018 printf_filtered ("LOC_REGPARM_ADDR %s: Collect %ld bytes at offset ",
3567439c 1019 SYMBOL_PRINT_NAME (sym), len);
104c1213
JM
1020 printf_vma (offset);
1021 printf_filtered (" from reg %d\n", reg);
c5aa993b
JM
1022 }
1023 add_memrange (collect, reg, offset, len);
1024 break;
1025 case LOC_LOCAL:
c5aa993b
JM
1026 reg = frame_regno;
1027 offset = frame_offset + SYMBOL_VALUE (sym);
1028 if (info_verbose)
1029 {
104c1213 1030 printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset ",
3567439c 1031 SYMBOL_PRINT_NAME (sym), len);
104c1213
JM
1032 printf_vma (offset);
1033 printf_filtered (" from frame ptr reg %d\n", reg);
c5aa993b
JM
1034 }
1035 add_memrange (collect, reg, offset, len);
1036 break;
c5aa993b 1037 case LOC_UNRESOLVED:
d183932d 1038 printf_filtered ("Don't know LOC_UNRESOLVED %s\n",
3567439c 1039 SYMBOL_PRINT_NAME (sym));
c5aa993b
JM
1040 break;
1041 case LOC_OPTIMIZED_OUT:
8e1a459b 1042 printf_filtered ("%s has been optimized out of existence.\n",
3567439c 1043 SYMBOL_PRINT_NAME (sym));
c5aa993b 1044 break;
0936ad1d
SS
1045
1046 case LOC_COMPUTED:
400c6af0 1047 treat_as_expr = 1;
0936ad1d 1048 break;
c5aa993b 1049 }
400c6af0
SS
1050
1051 /* Expressions are the most general case. */
1052 if (treat_as_expr)
1053 {
1054 struct agent_expr *aexpr;
1055 struct cleanup *old_chain1 = NULL;
1056 struct agent_reqs areqs;
1057
1058 aexpr = gen_trace_for_var (scope, gdbarch, sym);
1059
1060 /* It can happen that the symbol is recorded as a computed
1061 location, but it's been optimized away and doesn't actually
1062 have a location expression. */
1063 if (!aexpr)
1064 {
1065 printf_filtered ("%s has been optimized out of existence.\n",
1066 SYMBOL_PRINT_NAME (sym));
1067 return;
1068 }
1069
1070 old_chain1 = make_cleanup_free_agent_expr (aexpr);
1071
1072 ax_reqs (aexpr, &areqs);
1073 if (areqs.flaw != agent_flaw_none)
1074 error (_("malformed expression"));
1075
1076 if (areqs.min_height < 0)
1077 error (_("gdb: Internal error: expression has min height < 0"));
1078 if (areqs.max_height > 20)
1079 error (_("expression too complicated, try simplifying"));
1080
1081 discard_cleanups (old_chain1);
1082 add_aexpr (collect, aexpr);
1083
1084 /* take care of the registers */
1085 if (areqs.reg_mask_len > 0)
1086 {
1087 int ndx1, ndx2;
1088
1089 for (ndx1 = 0; ndx1 < areqs.reg_mask_len; ndx1++)
1090 {
1091 QUIT; /* allow user to bail out with ^C */
1092 if (areqs.reg_mask[ndx1] != 0)
1093 {
1094 /* assume chars have 8 bits */
1095 for (ndx2 = 0; ndx2 < 8; ndx2++)
1096 if (areqs.reg_mask[ndx1] & (1 << ndx2))
1097 /* it's used -- record it */
1098 add_register (collect, ndx1 * 8 + ndx2);
1099 }
1100 }
1101 }
1102 }
c906108c
SS
1103}
1104
1105/* Add all locals (or args) symbols to collection list */
1106static void
a6d9a66e
UW
1107add_local_symbols (struct collection_list *collect,
1108 struct gdbarch *gdbarch, CORE_ADDR pc,
fba45db2 1109 long frame_regno, long frame_offset, int type)
c906108c
SS
1110{
1111 struct symbol *sym;
c5aa993b 1112 struct block *block;
de4f826b
DC
1113 struct dict_iterator iter;
1114 int count = 0;
c906108c
SS
1115
1116 block = block_for_pc (pc);
1117 while (block != 0)
1118 {
c5aa993b 1119 QUIT; /* allow user to bail out with ^C */
de4f826b 1120 ALL_BLOCK_SYMBOLS (block, iter, sym)
c906108c 1121 {
2a2d4dc3
AS
1122 if (SYMBOL_IS_ARGUMENT (sym)
1123 ? type == 'A' /* collecting Arguments */
1124 : type == 'L') /* collecting Locals */
c5aa993b 1125 {
2a2d4dc3 1126 count++;
a6d9a66e 1127 collect_symbol (collect, sym, gdbarch,
0936ad1d 1128 frame_regno, frame_offset, pc);
c5aa993b 1129 }
c906108c
SS
1130 }
1131 if (BLOCK_FUNCTION (block))
1132 break;
1133 else
1134 block = BLOCK_SUPERBLOCK (block);
1135 }
1136 if (count == 0)
8a3fe4f8 1137 warning (_("No %s found in scope."),
d183932d 1138 type == 'L' ? "locals" : "args");
c906108c
SS
1139}
1140
1141/* worker function */
1142static void
fba45db2 1143clear_collection_list (struct collection_list *list)
c906108c
SS
1144{
1145 int ndx;
1146
1147 list->next_memrange = 0;
1148 for (ndx = 0; ndx < list->next_aexpr_elt; ndx++)
1149 {
c5aa993b 1150 free_agent_expr (list->aexpr_list[ndx]);
c906108c
SS
1151 list->aexpr_list[ndx] = NULL;
1152 }
1153 list->next_aexpr_elt = 0;
1154 memset (list->regs_mask, 0, sizeof (list->regs_mask));
1155}
1156
1157/* reduce a collection list to string form (for gdb protocol) */
1158static char **
fba45db2 1159stringify_collection_list (struct collection_list *list, char *string)
c906108c
SS
1160{
1161 char temp_buf[2048];
104c1213 1162 char tmp2[40];
c906108c
SS
1163 int count;
1164 int ndx = 0;
1165 char *(*str_list)[];
1166 char *end;
c5aa993b 1167 long i;
c906108c
SS
1168
1169 count = 1 + list->next_memrange + list->next_aexpr_elt + 1;
c5aa993b 1170 str_list = (char *(*)[]) xmalloc (count * sizeof (char *));
c906108c
SS
1171
1172 for (i = sizeof (list->regs_mask) - 1; i > 0; i--)
1173 if (list->regs_mask[i] != 0) /* skip leading zeroes in regs_mask */
1174 break;
1175 if (list->regs_mask[i] != 0) /* prepare to send regs_mask to the stub */
1176 {
1177 if (info_verbose)
1178 printf_filtered ("\nCollecting registers (mask): 0x");
1179 end = temp_buf;
c5aa993b 1180 *end++ = 'R';
c906108c
SS
1181 for (; i >= 0; i--)
1182 {
c5aa993b 1183 QUIT; /* allow user to bail out with ^C */
c906108c
SS
1184 if (info_verbose)
1185 printf_filtered ("%02X", list->regs_mask[i]);
c5aa993b 1186 sprintf (end, "%02X", list->regs_mask[i]);
c906108c
SS
1187 end += 2;
1188 }
1b36a34b 1189 (*str_list)[ndx] = xstrdup (temp_buf);
c906108c
SS
1190 ndx++;
1191 }
1192 if (info_verbose)
1193 printf_filtered ("\n");
1194 if (list->next_memrange > 0 && info_verbose)
1195 printf_filtered ("Collecting memranges: \n");
1196 for (i = 0, count = 0, end = temp_buf; i < list->next_memrange; i++)
1197 {
1198 QUIT; /* allow user to bail out with ^C */
104c1213 1199 sprintf_vma (tmp2, list->list[i].start);
c906108c 1200 if (info_verbose)
104c1213
JM
1201 {
1202 printf_filtered ("(%d, %s, %ld)\n",
1203 list->list[i].type,
1204 tmp2,
1205 (long) (list->list[i].end - list->list[i].start));
1206 }
c906108c
SS
1207 if (count + 27 > MAX_AGENT_EXPR_LEN)
1208 {
c5aa993b 1209 (*str_list)[ndx] = savestring (temp_buf, count);
c906108c
SS
1210 ndx++;
1211 count = 0;
1212 end = temp_buf;
1213 }
104c1213 1214
d1948716
JB
1215 {
1216 bfd_signed_vma length = list->list[i].end - list->list[i].start;
1217
1218 /* The "%X" conversion specifier expects an unsigned argument,
f50e79a4
JB
1219 so passing -1 (memrange_absolute) to it directly gives you
1220 "FFFFFFFF" (or more, depending on sizeof (unsigned)).
1221 Special-case it. */
1222 if (list->list[i].type == memrange_absolute)
d1948716
JB
1223 sprintf (end, "M-1,%s,%lX", tmp2, (long) length);
1224 else
1225 sprintf (end, "M%X,%s,%lX", list->list[i].type, tmp2, (long) length);
1226 }
104c1213 1227
c906108c 1228 count += strlen (end);
3ffbc0a5 1229 end = temp_buf + count;
c906108c
SS
1230 }
1231
1232 for (i = 0; i < list->next_aexpr_elt; i++)
1233 {
1234 QUIT; /* allow user to bail out with ^C */
1235 if ((count + 10 + 2 * list->aexpr_list[i]->len) > MAX_AGENT_EXPR_LEN)
1236 {
c5aa993b 1237 (*str_list)[ndx] = savestring (temp_buf, count);
c906108c
SS
1238 ndx++;
1239 count = 0;
1240 end = temp_buf;
1241 }
1242 sprintf (end, "X%08X,", list->aexpr_list[i]->len);
1243 end += 10; /* 'X' + 8 hex digits + ',' */
1244 count += 10;
1245
d183932d
MS
1246 end = mem2hex (list->aexpr_list[i]->buf,
1247 end, list->aexpr_list[i]->len);
c906108c
SS
1248 count += 2 * list->aexpr_list[i]->len;
1249 }
1250
1251 if (count != 0)
1252 {
c5aa993b 1253 (*str_list)[ndx] = savestring (temp_buf, count);
c906108c
SS
1254 ndx++;
1255 count = 0;
1256 end = temp_buf;
1257 }
1258 (*str_list)[ndx] = NULL;
1259
1260 if (ndx == 0)
27e06d3e 1261 {
6c761d9c 1262 xfree (str_list);
27e06d3e
MS
1263 return NULL;
1264 }
c906108c
SS
1265 else
1266 return *str_list;
1267}
1268
d183932d 1269/* Render all actions into gdb protocol. */
35b1e5cc 1270/*static*/ void
9355b391
SS
1271encode_actions (struct breakpoint *t, struct bp_location *tloc,
1272 char ***tdp_actions, char ***stepping_actions)
c906108c 1273{
c5aa993b
JM
1274 static char tdp_buff[2048], step_buff[2048];
1275 char *action_exp;
1276 struct expression *exp = NULL;
c906108c 1277 struct action_line *action;
104c1213 1278 int i;
f976f6d4 1279 struct value *tempval;
c5aa993b 1280 struct collection_list *collect;
c906108c
SS
1281 struct cmd_list_element *cmd;
1282 struct agent_expr *aexpr;
39d4ef09
AC
1283 int frame_reg;
1284 LONGEST frame_offset;
236f1d4d
SS
1285 char *default_collect_line = NULL;
1286 struct action_line *default_collect_action = NULL;
c906108c
SS
1287
1288 clear_collection_list (&tracepoint_list);
1289 clear_collection_list (&stepping_list);
1290 collect = &tracepoint_list;
1291
1292 *tdp_actions = NULL;
1293 *stepping_actions = NULL;
1294
a6d9a66e 1295 gdbarch_virtual_frame_pointer (t->gdbarch,
9355b391 1296 tloc->address, &frame_reg, &frame_offset);
c906108c 1297
236f1d4d
SS
1298 action = t->actions;
1299
1300 /* If there are default expressions to collect, make up a collect
1301 action and prepend to the action list to encode. Note that since
1302 validation is per-tracepoint (local var "xyz" might be valid for
1303 one tracepoint and not another, etc), we make up the action on
1304 the fly, and don't cache it. */
1305 if (*default_collect)
1306 {
1307 char *line;
1308 enum actionline_type linetype;
1309
1310 default_collect_line = xmalloc (12 + strlen (default_collect));
1311 sprintf (default_collect_line, "collect %s", default_collect);
1312 line = default_collect_line;
1313 linetype = validate_actionline (&line, t);
1314 if (linetype != BADLINE)
1315 {
1316 default_collect_action = xmalloc (sizeof (struct action_line));
1317 default_collect_action->next = t->actions;
1318 default_collect_action->action = line;
1319 action = default_collect_action;
1320 }
1321 }
1322
1323 for (; action; action = action->next)
c906108c
SS
1324 {
1325 QUIT; /* allow user to bail out with ^C */
1326 action_exp = action->action;
104c1213 1327 while (isspace ((int) *action_exp))
c906108c
SS
1328 action_exp++;
1329
1330 if (*action_exp == '#') /* comment line */
1331 return;
1332
1333 cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
1334 if (cmd == 0)
8a3fe4f8 1335 error (_("Bad action list item: %s"), action_exp);
c906108c 1336
bbaca940 1337 if (cmd_cfunc_eq (cmd, collect_pseudocommand))
c906108c 1338 {
c5aa993b
JM
1339 do
1340 { /* repeat over a comma-separated list */
1341 QUIT; /* allow user to bail out with ^C */
104c1213 1342 while (isspace ((int) *action_exp))
c5aa993b 1343 action_exp++;
c906108c 1344
c5aa993b
JM
1345 if (0 == strncasecmp ("$reg", action_exp, 4))
1346 {
a6d9a66e 1347 for (i = 0; i < gdbarch_num_regs (t->gdbarch); i++)
c5aa993b
JM
1348 add_register (collect, i);
1349 action_exp = strchr (action_exp, ','); /* more? */
1350 }
1351 else if (0 == strncasecmp ("$arg", action_exp, 4))
1352 {
1353 add_local_symbols (collect,
a6d9a66e 1354 t->gdbarch,
9355b391 1355 tloc->address,
c5aa993b
JM
1356 frame_reg,
1357 frame_offset,
1358 'A');
1359 action_exp = strchr (action_exp, ','); /* more? */
1360 }
1361 else if (0 == strncasecmp ("$loc", action_exp, 4))
1362 {
1363 add_local_symbols (collect,
a6d9a66e 1364 t->gdbarch,
9355b391 1365 tloc->address,
c5aa993b
JM
1366 frame_reg,
1367 frame_offset,
1368 'L');
1369 action_exp = strchr (action_exp, ','); /* more? */
1370 }
1371 else
1372 {
1373 unsigned long addr, len;
1374 struct cleanup *old_chain = NULL;
1375 struct cleanup *old_chain1 = NULL;
1376 struct agent_reqs areqs;
1377
75ac9d7b 1378 exp = parse_exp_1 (&action_exp,
9355b391 1379 block_for_pc (tloc->address), 1);
74b7792f 1380 old_chain = make_cleanup (free_current_contents, &exp);
c906108c 1381
c5aa993b
JM
1382 switch (exp->elts[0].opcode)
1383 {
1384 case OP_REGISTER:
67f3407f
DJ
1385 {
1386 const char *name = &exp->elts[2].string;
1387
a6d9a66e 1388 i = user_reg_map_name_to_regnum (t->gdbarch,
029a67e4 1389 name, strlen (name));
67f3407f
DJ
1390 if (i == -1)
1391 internal_error (__FILE__, __LINE__,
1392 _("Register $%s not available"),
1393 name);
1394 if (info_verbose)
1395 printf_filtered ("OP_REGISTER: ");
1396 add_register (collect, i);
1397 break;
1398 }
c5aa993b
JM
1399
1400 case UNOP_MEMVAL:
1401 /* safe because we know it's a simple expression */
1402 tempval = evaluate_expression (exp);
42ae5230 1403 addr = value_address (tempval);
c5aa993b 1404 len = TYPE_LENGTH (check_typedef (exp->elts[1].type));
f50e79a4 1405 add_memrange (collect, memrange_absolute, addr, len);
c5aa993b
JM
1406 break;
1407
1408 case OP_VAR_VALUE:
1409 collect_symbol (collect,
1410 exp->elts[2].symbol,
a6d9a66e 1411 t->gdbarch,
c5aa993b 1412 frame_reg,
0936ad1d 1413 frame_offset,
9355b391 1414 tloc->address);
c5aa993b
JM
1415 break;
1416
1417 default: /* full-fledged expression */
9355b391 1418 aexpr = gen_trace_for_expr (tloc->address, exp);
c5aa993b 1419
f23d52e0 1420 old_chain1 = make_cleanup_free_agent_expr (aexpr);
c5aa993b
JM
1421
1422 ax_reqs (aexpr, &areqs);
1423 if (areqs.flaw != agent_flaw_none)
8a3fe4f8 1424 error (_("malformed expression"));
c5aa993b
JM
1425
1426 if (areqs.min_height < 0)
8a3fe4f8 1427 error (_("gdb: Internal error: expression has min height < 0"));
c5aa993b 1428 if (areqs.max_height > 20)
8a3fe4f8 1429 error (_("expression too complicated, try simplifying"));
c5aa993b
JM
1430
1431 discard_cleanups (old_chain1);
1432 add_aexpr (collect, aexpr);
1433
1434 /* take care of the registers */
1435 if (areqs.reg_mask_len > 0)
c906108c 1436 {
c5aa993b
JM
1437 int ndx1;
1438 int ndx2;
1439
1440 for (ndx1 = 0; ndx1 < areqs.reg_mask_len; ndx1++)
c906108c 1441 {
c5aa993b
JM
1442 QUIT; /* allow user to bail out with ^C */
1443 if (areqs.reg_mask[ndx1] != 0)
1444 {
1445 /* assume chars have 8 bits */
1446 for (ndx2 = 0; ndx2 < 8; ndx2++)
1447 if (areqs.reg_mask[ndx1] & (1 << ndx2))
1448 /* it's used -- record it */
d183932d
MS
1449 add_register (collect,
1450 ndx1 * 8 + ndx2);
c5aa993b 1451 }
c906108c
SS
1452 }
1453 }
c5aa993b
JM
1454 break;
1455 } /* switch */
1456 do_cleanups (old_chain);
1457 } /* do */
1458 }
1459 while (action_exp && *action_exp++ == ',');
1460 } /* if */
6da95a67
SS
1461 else if (cmd_cfunc_eq (cmd, teval_pseudocommand))
1462 {
1463 do
1464 { /* repeat over a comma-separated list */
1465 QUIT; /* allow user to bail out with ^C */
1466 while (isspace ((int) *action_exp))
1467 action_exp++;
1468
1469 {
1470 unsigned long addr, len;
1471 struct cleanup *old_chain = NULL;
1472 struct cleanup *old_chain1 = NULL;
1473 struct agent_reqs areqs;
1474
1475 exp = parse_exp_1 (&action_exp,
9355b391 1476 block_for_pc (tloc->address), 1);
6da95a67
SS
1477 old_chain = make_cleanup (free_current_contents, &exp);
1478
9355b391 1479 aexpr = gen_eval_for_expr (tloc->address, exp);
6da95a67
SS
1480 old_chain1 = make_cleanup_free_agent_expr (aexpr);
1481
1482 ax_reqs (aexpr, &areqs);
1483 if (areqs.flaw != agent_flaw_none)
1484 error (_("malformed expression"));
1485
1486 if (areqs.min_height < 0)
1487 error (_("gdb: Internal error: expression has min height < 0"));
1488 if (areqs.max_height > 20)
1489 error (_("expression too complicated, try simplifying"));
1490
1491 discard_cleanups (old_chain1);
1492 /* Even though we're not officially collecting, add
1493 to the collect list anyway. */
1494 add_aexpr (collect, aexpr);
1495
1496 do_cleanups (old_chain);
1497 } /* do */
1498 }
1499 while (action_exp && *action_exp++ == ',');
1500 } /* if */
bbaca940 1501 else if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand))
c906108c
SS
1502 {
1503 collect = &stepping_list;
1504 }
bbaca940 1505 else if (cmd_cfunc_eq (cmd, end_actions_pseudocommand))
c906108c
SS
1506 {
1507 if (collect == &stepping_list) /* end stepping actions */
1508 collect = &tracepoint_list;
1509 else
c5aa993b 1510 break; /* end tracepoint actions */
c906108c 1511 }
c5aa993b
JM
1512 } /* for */
1513 memrange_sortmerge (&tracepoint_list);
1514 memrange_sortmerge (&stepping_list);
c906108c 1515
d183932d
MS
1516 *tdp_actions = stringify_collection_list (&tracepoint_list,
1517 tdp_buff);
1518 *stepping_actions = stringify_collection_list (&stepping_list,
1519 step_buff);
236f1d4d
SS
1520
1521 xfree (default_collect_line);
1522 xfree (default_collect_action);
c906108c
SS
1523}
1524
1525static void
fba45db2 1526add_aexpr (struct collection_list *collect, struct agent_expr *aexpr)
c906108c
SS
1527{
1528 if (collect->next_aexpr_elt >= collect->aexpr_listsize)
1529 {
1530 collect->aexpr_list =
1531 xrealloc (collect->aexpr_list,
c5aa993b 1532 2 * collect->aexpr_listsize * sizeof (struct agent_expr *));
c906108c
SS
1533 collect->aexpr_listsize *= 2;
1534 }
1535 collect->aexpr_list[collect->next_aexpr_elt] = aexpr;
1536 collect->next_aexpr_elt++;
1537}
1538
c906108c 1539/* tstart command:
c5aa993b 1540
c906108c
SS
1541 Tell target to clear any previous trace experiment.
1542 Walk the list of tracepoints, and send them (and their actions)
1543 to the target. If no errors,
1544 Tell target to start a new trace experiment. */
1545
1546static void
fba45db2 1547trace_start_command (char *args, int from_tty)
d183932d 1548{
f61e138d 1549 char buf[2048];
1042e4c0
SS
1550 VEC(breakpoint_p) *tp_vec = NULL;
1551 int ix;
1552 struct breakpoint *t;
f61e138d 1553 struct trace_state_variable *tsv;
d5551862 1554 int any_downloaded = 0;
c906108c 1555
d183932d 1556 dont_repeat (); /* Like "run", dangerous to repeat accidentally. */
c5aa993b 1557
35b1e5cc
SS
1558 target_trace_init ();
1559
1560 tp_vec = all_tracepoints ();
1561 for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, t); ix++)
7a697b8d 1562 {
35b1e5cc
SS
1563 t->number_on_target = 0;
1564 target_download_tracepoint (t);
1565 t->number_on_target = t->number;
1566 any_downloaded = 1;
7a697b8d 1567 }
35b1e5cc
SS
1568 VEC_free (breakpoint_p, tp_vec);
1569
1570 /* No point in tracing without any tracepoints... */
1571 if (!any_downloaded)
1572 error ("No tracepoints downloaded, not starting trace");
1573
00bf0b85 1574 /* Send down all the trace state variables too. */
35b1e5cc 1575 for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
782b2b07 1576 {
00bf0b85 1577 target_download_trace_state_variable (tsv);
782b2b07 1578 }
35b1e5cc
SS
1579
1580 /* Tell target to treat text-like sections as transparent. */
1581 target_trace_set_readonly_regions ();
1042e4c0 1582
35b1e5cc
SS
1583 /* Now insert traps and begin collecting data. */
1584 target_trace_start ();
1042e4c0 1585
35b1e5cc
SS
1586 /* Reset our local state. */
1587 set_traceframe_num (-1);
1588 set_tracepoint_num (-1);
1589 set_traceframe_context (NULL);
00bf0b85 1590 current_trace_status()->running = 1;
1042e4c0
SS
1591}
1592
c906108c
SS
1593/* tstop command */
1594static void
fba45db2 1595trace_stop_command (char *args, int from_tty)
d183932d 1596{
35b1e5cc 1597 stop_tracing ();
c906108c
SS
1598}
1599
d5551862
SS
1600void
1601stop_tracing ()
1602{
35b1e5cc 1603 target_trace_stop ();
00bf0b85
SS
1604 /* should change in response to reply? */
1605 current_trace_status ()->running = 0;
d5551862
SS
1606}
1607
c906108c
SS
1608/* tstatus command */
1609static void
fba45db2 1610trace_status_command (char *args, int from_tty)
d183932d 1611{
00bf0b85
SS
1612 struct trace_status *ts = current_trace_status ();
1613 int status;
35b1e5cc 1614
00bf0b85
SS
1615 status = target_get_trace_status (ts);
1616
1617 if (status == -1)
1618 {
1619 if (ts->from_file)
1620 printf_filtered (_("Using a trace file.\n"));
1621 else
1622 {
1623 printf_filtered (_("Trace can not be run on this target.\n"));
1624 return;
1625 }
1626 }
1627
1628 if (!ts->running_known)
1629 {
1630 printf_filtered (_("Run/stop status is unknown.\n"));
1631 }
1632 else if (ts->running)
c906108c 1633 {
35b1e5cc
SS
1634 printf_filtered (_("Trace is running on the target.\n"));
1635 if (disconnected_tracing)
1636 printf_filtered (_("Trace will continue if GDB disconnects.\n"));
d3513012 1637 else
35b1e5cc 1638 printf_filtered (_("Trace will stop if GDB disconnects.\n"));
c906108c
SS
1639 }
1640 else
00bf0b85
SS
1641 {
1642 switch (ts->stop_reason)
1643 {
1644 case trace_never_run:
1645 printf_filtered (_("No trace has been run on the target.\n"));
1646 break;
1647 case tstop_command:
1648 printf_filtered (_("Trace stopped by a tstop command.\n"));
1649 break;
1650 case trace_buffer_full:
1651 printf_filtered (_("Trace stopped because the buffer was full.\n"));
1652 break;
1653 case trace_disconnected:
1654 printf_filtered (_("Trace stopped because of disconnection.\n"));
1655 break;
1656 case tracepoint_passcount:
1657 /* FIXME account for number on target */
1658 printf_filtered (_("Trace stopped by tracepoint %d.\n"),
1659 ts->stopping_tracepoint);
1660 break;
1661 case trace_stop_reason_unknown:
1662 printf_filtered (_("Trace stopped for an unknown reason.\n"));
1663 break;
1664 default:
1665 printf_filtered (_("Trace stopped for some other reason (%d).\n"),
1666 ts->stop_reason);
1667 break;
1668 }
1669 }
1670
1671 if (ts->traceframe_count >= 0)
1672 {
1673 printf_filtered (_("Collected %d trace frames.\n"),
1674 ts->traceframe_count);
1675 }
1676
1677 if (ts->buffer_free)
1678 {
98e03262 1679 printf_filtered (_("Trace buffer has %llu bytes free.\n"),
00bf0b85
SS
1680 ts->buffer_free);
1681 }
35b1e5cc 1682
00bf0b85 1683 /* Now report on what we're doing with tfind. */
35b1e5cc
SS
1684 if (traceframe_number >= 0)
1685 printf_filtered (_("Looking at trace frame %d, tracepoint %d.\n"),
1686 traceframe_number, tracepoint_number);
1687 else
1688 printf_filtered (_("Not looking at any trace frame.\n"));
c906108c
SS
1689}
1690
d5551862
SS
1691void
1692disconnect_or_stop_tracing (int from_tty)
1693{
00bf0b85
SS
1694 /* It can happen that the target that was tracing went away on its
1695 own, and we didn't notice. Get a status update, and if the
1696 current target doesn't even do tracing, then assume it's not
1697 running anymore. */
1698 if (target_get_trace_status (current_trace_status ()) < 0)
1699 current_trace_status ()->running = 0;
1700
1701 if (current_trace_status ()->running && from_tty)
d5551862
SS
1702 {
1703 int cont = query (_("Trace is running. Continue tracing after detach? "));
1704 /* Note that we send the query result without affecting the
1705 user's setting of disconnected_tracing, so that the answer is
1706 a one-time-only. */
1707 send_disconnected_tracing_value (cont);
1708
1709 /* Also ensure that we do the equivalent of a tstop command if
1710 tracing is not to continue after the detach. */
1711 if (!cont)
1712 stop_tracing ();
1713 }
1714}
1715
d183932d 1716/* Worker function for the various flavors of the tfind command. */
c906108c 1717static void
35b1e5cc
SS
1718finish_tfind_command (enum trace_find_type type, int num,
1719 ULONGEST addr1, ULONGEST addr2,
c2d11a7d 1720 int from_tty)
c906108c
SS
1721{
1722 int target_frameno = -1, target_tracept = -1;
fb14de7b 1723 struct frame_id old_frame_id;
c906108c 1724 char *reply;
d5551862 1725 struct breakpoint *tp;
c906108c 1726
fb14de7b 1727 old_frame_id = get_frame_id (get_current_frame ());
c906108c 1728
35b1e5cc
SS
1729 target_frameno = target_trace_find (type, num, addr1, addr2,
1730 &target_tracept);
1731
1732 if (type == tfind_number
1733 && num == -1
1734 && target_frameno == -1)
1735 {
1736 /* We told the target to get out of tfind mode, and it did. */
1737 }
1738 else if (target_frameno == -1)
1739 {
1740 /* A request for a non-existant trace frame has failed.
1741 Our response will be different, depending on FROM_TTY:
1742
1743 If FROM_TTY is true, meaning that this command was
1744 typed interactively by the user, then give an error
1745 and DO NOT change the state of traceframe_number etc.
1746
1747 However if FROM_TTY is false, meaning that we're either
1748 in a script, a loop, or a user-defined command, then
1749 DON'T give an error, but DO change the state of
1750 traceframe_number etc. to invalid.
1751
1752 The rationalle is that if you typed the command, you
1753 might just have committed a typo or something, and you'd
1754 like to NOT lose your current debugging state. However
1755 if you're in a user-defined command or especially in a
1756 loop, then you need a way to detect that the command
1757 failed WITHOUT aborting. This allows you to write
1758 scripts that search thru the trace buffer until the end,
1759 and then continue on to do something else. */
1760
1761 if (from_tty)
1762 error (_("Target failed to find requested trace frame."));
1763 else
1764 {
1765 if (info_verbose)
1766 printf_filtered ("End of trace buffer.\n");
1767#if 0 /* dubious now? */
1768 /* The following will not recurse, since it's
1769 special-cased. */
1770 trace_find_command ("-1", from_tty);
1771#endif
1772 }
1773 }
1774
d5551862
SS
1775 tp = get_tracepoint_by_number_on_target (target_tracept);
1776
35f196d9 1777 reinit_frame_cache ();
c906108c 1778 registers_changed ();
2f4d8875 1779 target_dcache_invalidate ();
c906108c 1780 set_traceframe_num (target_frameno);
d5551862 1781 set_tracepoint_num (tp ? tp->number : target_tracept);
c906108c 1782 if (target_frameno == -1)
fb14de7b 1783 set_traceframe_context (NULL);
c906108c 1784 else
fb14de7b 1785 set_traceframe_context (get_current_frame ());
c906108c 1786
00bf0b85
SS
1787 /* If we're in nonstop mode and getting out of looking at trace
1788 frames, there won't be any current frame to go back to and
1789 display. */
1790 if (from_tty
1791 && (has_stack_frames () || traceframe_number >= 0))
c906108c 1792 {
0faf0076 1793 enum print_what print_what;
c906108c
SS
1794
1795 /* NOTE: in immitation of the step command, try to determine
d183932d
MS
1796 whether we have made a transition from one function to
1797 another. If so, we'll print the "stack frame" (ie. the new
1798 function and it's arguments) -- otherwise we'll just show the
fb14de7b
UW
1799 new source line. */
1800
1801 if (frame_id_eq (old_frame_id,
1802 get_frame_id (get_current_frame ())))
0faf0076 1803 print_what = SRC_LINE;
c906108c 1804 else
0faf0076 1805 print_what = SRC_AND_LOC;
c906108c 1806
b04f3ab4 1807 print_stack_frame (get_selected_frame (NULL), 1, print_what);
c906108c
SS
1808 do_displays ();
1809 }
1810}
1811
1812/* trace_find_command takes a trace frame number n,
1813 sends "QTFrame:<n>" to the target,
1814 and accepts a reply that may contain several optional pieces
1815 of information: a frame number, a tracepoint number, and an
1816 indication of whether this is a trap frame or a stepping frame.
1817
1818 The minimal response is just "OK" (which indicates that the
1819 target does not give us a frame number or a tracepoint number).
1820 Instead of that, the target may send us a string containing
1821 any combination of:
c5aa993b
JM
1822 F<hexnum> (gives the selected frame number)
1823 T<hexnum> (gives the selected tracepoint number)
1824 */
c906108c
SS
1825
1826/* tfind command */
1827static void
fba45db2 1828trace_find_command (char *args, int from_tty)
d183932d 1829{ /* this should only be called with a numeric argument */
c906108c 1830 int frameno = -1;
c906108c 1831
00bf0b85 1832 if (current_trace_status ()->running && !current_trace_status ()->from_file)
35b1e5cc
SS
1833 error ("May not look at trace frames while trace is running.");
1834
1835 if (args == 0 || *args == 0)
1836 { /* TFIND with no args means find NEXT trace frame. */
1837 if (traceframe_number == -1)
1838 frameno = 0; /* "next" is first one */
1839 else
1840 frameno = traceframe_number + 1;
1841 }
1842 else if (0 == strcmp (args, "-"))
c906108c 1843 {
35b1e5cc
SS
1844 if (traceframe_number == -1)
1845 error (_("not debugging trace buffer"));
1846 else if (from_tty && traceframe_number == 0)
1847 error (_("already at start of trace buffer"));
1848
1849 frameno = traceframe_number - 1;
1850 }
1851 /* A hack to work around eval's need for fp to have been collected. */
1852 else if (0 == strcmp (args, "-1"))
1853 frameno = -1;
1854 else
1855 frameno = parse_and_eval_long (args);
c906108c 1856
35b1e5cc
SS
1857 if (frameno < -1)
1858 error (_("invalid input (%d is less than zero)"), frameno);
c906108c 1859
35b1e5cc 1860 finish_tfind_command (tfind_number, frameno, 0, 0, from_tty);
c906108c
SS
1861}
1862
1863/* tfind end */
1864static void
fba45db2 1865trace_find_end_command (char *args, int from_tty)
c906108c
SS
1866{
1867 trace_find_command ("-1", from_tty);
1868}
1869
1870/* tfind none */
1871static void
fba45db2 1872trace_find_none_command (char *args, int from_tty)
c906108c
SS
1873{
1874 trace_find_command ("-1", from_tty);
1875}
1876
1877/* tfind start */
1878static void
fba45db2 1879trace_find_start_command (char *args, int from_tty)
c906108c
SS
1880{
1881 trace_find_command ("0", from_tty);
1882}
1883
1884/* tfind pc command */
1885static void
fba45db2 1886trace_find_pc_command (char *args, int from_tty)
d183932d 1887{
c906108c 1888 CORE_ADDR pc;
104c1213 1889 char tmp[40];
c906108c 1890
00bf0b85 1891 if (current_trace_status ()->running && !current_trace_status ()->from_file)
35b1e5cc 1892 error ("May not look at trace frames while trace is running.");
c906108c 1893
35b1e5cc
SS
1894 if (args == 0 || *args == 0)
1895 pc = regcache_read_pc (get_current_regcache ());
c906108c 1896 else
35b1e5cc
SS
1897 pc = parse_and_eval_address (args);
1898
1899 finish_tfind_command (tfind_pc, 0, pc, 0, from_tty);
c906108c
SS
1900}
1901
1902/* tfind tracepoint command */
1903static void
fba45db2 1904trace_find_tracepoint_command (char *args, int from_tty)
d183932d 1905{
c906108c 1906 int tdp;
d5551862 1907 struct breakpoint *tp;
c906108c 1908
00bf0b85 1909 if (current_trace_status ()->running && !current_trace_status ()->from_file)
35b1e5cc 1910 error ("May not look at trace frames while trace is running.");
383e5f85 1911
35b1e5cc
SS
1912 if (args == 0 || *args == 0)
1913 {
1914 if (tracepoint_number == -1)
1915 error (_("No current tracepoint -- please supply an argument."));
c906108c 1916 else
35b1e5cc 1917 tdp = tracepoint_number; /* default is current TDP */
c906108c
SS
1918 }
1919 else
35b1e5cc
SS
1920 tdp = parse_and_eval_long (args);
1921
1922 /* If we have the tracepoint on hand, use the number that the
1923 target knows about (which may be different if we disconnected
1924 and reconnected). */
1925 tp = get_tracepoint (tdp);
1926 if (tp)
1927 tdp = tp->number_on_target;
1928
1929 finish_tfind_command (tfind_tp, tdp, 0, 0, from_tty);
c906108c
SS
1930}
1931
1932/* TFIND LINE command:
c5aa993b 1933
c906108c 1934 This command will take a sourceline for argument, just like BREAK
d183932d 1935 or TRACE (ie. anything that "decode_line_1" can handle).
c5aa993b 1936
c906108c
SS
1937 With no argument, this command will find the next trace frame
1938 corresponding to a source line OTHER THAN THE CURRENT ONE. */
1939
1940static void
fba45db2 1941trace_find_line_command (char *args, int from_tty)
d183932d 1942{
c906108c
SS
1943 static CORE_ADDR start_pc, end_pc;
1944 struct symtabs_and_lines sals;
1945 struct symtab_and_line sal;
c906108c 1946 struct cleanup *old_chain;
104c1213 1947 char startpc_str[40], endpc_str[40];
c906108c 1948
00bf0b85 1949 if (current_trace_status ()->running && !current_trace_status ()->from_file)
35b1e5cc 1950 error ("May not look at trace frames while trace is running.");
5af949e3 1951
35b1e5cc
SS
1952 if (args == 0 || *args == 0)
1953 {
1954 sal = find_pc_line (get_frame_pc (get_current_frame ()), 0);
1955 sals.nelts = 1;
1956 sals.sals = (struct symtab_and_line *)
1957 xmalloc (sizeof (struct symtab_and_line));
1958 sals.sals[0] = sal;
1959 }
1960 else
1961 {
1962 sals = decode_line_spec (args, 1);
1963 sal = sals.sals[0];
1964 }
1965
1966 old_chain = make_cleanup (xfree, sals.sals);
1967 if (sal.symtab == 0)
1968 {
1969 printf_filtered ("TFIND: No line number information available");
1970 if (sal.pc != 0)
c906108c 1971 {
35b1e5cc
SS
1972 /* This is useful for "info line *0x7f34". If we can't
1973 tell the user about a source line, at least let them
1974 have the symbolic address. */
1975 printf_filtered (" for address ");
1976 wrap_here (" ");
1977 print_address (get_current_arch (), sal.pc, gdb_stdout);
1978 printf_filtered (";\n -- will attempt to find by PC. \n");
1979 }
1980 else
1981 {
1982 printf_filtered (".\n");
1983 return; /* No line, no PC; what can we do? */
1984 }
c906108c 1985 }
35b1e5cc
SS
1986 else if (sal.line > 0
1987 && find_line_pc_range (sal, &start_pc, &end_pc))
1988 {
1989 if (start_pc == end_pc)
1990 {
1991 printf_filtered ("Line %d of \"%s\"",
1992 sal.line, sal.symtab->filename);
1993 wrap_here (" ");
1994 printf_filtered (" is at address ");
1995 print_address (get_current_arch (), start_pc, gdb_stdout);
1996 wrap_here (" ");
1997 printf_filtered (" but contains no code.\n");
1998 sal = find_pc_line (start_pc, 0);
1999 if (sal.line > 0
2000 && find_line_pc_range (sal, &start_pc, &end_pc)
2001 && start_pc != end_pc)
2002 printf_filtered ("Attempting to find line %d instead.\n",
2003 sal.line);
2004 else
2005 error (_("Cannot find a good line."));
2006 }
2007 }
2008 else
2009 /* Is there any case in which we get here, and have an address
2010 which the user would want to see? If we have debugging
2011 symbols and no line numbers? */
2012 error (_("Line number %d is out of range for \"%s\"."),
2013 sal.line, sal.symtab->filename);
2014
2015 /* Find within range of stated line. */
2016 if (args && *args)
2017 finish_tfind_command (tfind_range, 0, start_pc, end_pc - 1, from_tty);
c906108c 2018 else
35b1e5cc
SS
2019 finish_tfind_command (tfind_outside, 0, start_pc, end_pc - 1, from_tty);
2020 do_cleanups (old_chain);
c906108c
SS
2021}
2022
2023/* tfind range command */
2024static void
fba45db2 2025trace_find_range_command (char *args, int from_tty)
104c1213 2026{
c906108c 2027 static CORE_ADDR start, stop;
104c1213 2028 char start_str[40], stop_str[40];
c906108c
SS
2029 char *tmp;
2030
00bf0b85 2031 if (current_trace_status ()->running && !current_trace_status ()->from_file)
35b1e5cc 2032 error ("May not look at trace frames while trace is running.");
c906108c 2033
35b1e5cc
SS
2034 if (args == 0 || *args == 0)
2035 { /* XXX FIXME: what should default behavior be? */
2036 printf_filtered ("Usage: tfind range <startaddr>,<endaddr>\n");
2037 return;
2038 }
c906108c 2039
35b1e5cc
SS
2040 if (0 != (tmp = strchr (args, ',')))
2041 {
2042 *tmp++ = '\0'; /* terminate start address */
2043 while (isspace ((int) *tmp))
2044 tmp++;
2045 start = parse_and_eval_address (args);
2046 stop = parse_and_eval_address (tmp);
c906108c
SS
2047 }
2048 else
35b1e5cc
SS
2049 { /* no explicit end address? */
2050 start = parse_and_eval_address (args);
2051 stop = start + 1; /* ??? */
2052 }
2053
2054 finish_tfind_command (tfind_range, 0, start, stop, from_tty);
c906108c
SS
2055}
2056
2057/* tfind outside command */
2058static void
fba45db2 2059trace_find_outside_command (char *args, int from_tty)
104c1213 2060{
c906108c 2061 CORE_ADDR start, stop;
104c1213 2062 char start_str[40], stop_str[40];
c906108c
SS
2063 char *tmp;
2064
00bf0b85 2065 if (current_trace_status ()->running && !current_trace_status ()->from_file)
35b1e5cc 2066 error ("May not look at trace frames while trace is running.");
c906108c 2067
35b1e5cc
SS
2068 if (args == 0 || *args == 0)
2069 { /* XXX FIXME: what should default behavior be? */
2070 printf_filtered ("Usage: tfind outside <startaddr>,<endaddr>\n");
2071 return;
2072 }
c906108c 2073
35b1e5cc
SS
2074 if (0 != (tmp = strchr (args, ',')))
2075 {
2076 *tmp++ = '\0'; /* terminate start address */
2077 while (isspace ((int) *tmp))
2078 tmp++;
2079 start = parse_and_eval_address (args);
2080 stop = parse_and_eval_address (tmp);
c906108c
SS
2081 }
2082 else
35b1e5cc
SS
2083 { /* no explicit end address? */
2084 start = parse_and_eval_address (args);
2085 stop = start + 1; /* ??? */
2086 }
2087
2088 finish_tfind_command (tfind_outside, 0, start, stop, from_tty);
c906108c
SS
2089}
2090
c906108c
SS
2091/* info scope command: list the locals for a scope. */
2092static void
fba45db2 2093scope_info (char *args, int from_tty)
c906108c 2094{
c906108c
SS
2095 struct symtabs_and_lines sals;
2096 struct symbol *sym;
2097 struct minimal_symbol *msym;
2098 struct block *block;
2099 char **canonical, *symname, *save_args = args;
de4f826b
DC
2100 struct dict_iterator iter;
2101 int j, count = 0;
768a979c
UW
2102 struct gdbarch *gdbarch;
2103 int regno;
c906108c
SS
2104
2105 if (args == 0 || *args == 0)
8a3fe4f8 2106 error (_("requires an argument (function, line or *addr) to define a scope"));
c906108c 2107
68219205 2108 sals = decode_line_1 (&args, 1, NULL, 0, &canonical, NULL);
c906108c 2109 if (sals.nelts == 0)
450bd37b 2110 return; /* presumably decode_line_1 has already warned */
c906108c
SS
2111
2112 /* Resolve line numbers to PC */
2113 resolve_sal_pc (&sals.sals[0]);
2114 block = block_for_pc (sals.sals[0].pc);
2115
2116 while (block != 0)
2117 {
c5aa993b 2118 QUIT; /* allow user to bail out with ^C */
de4f826b 2119 ALL_BLOCK_SYMBOLS (block, iter, sym)
c906108c 2120 {
c5aa993b 2121 QUIT; /* allow user to bail out with ^C */
c906108c
SS
2122 if (count == 0)
2123 printf_filtered ("Scope for %s:\n", save_args);
2124 count++;
e88c90f2 2125
3567439c 2126 symname = SYMBOL_PRINT_NAME (sym);
c906108c 2127 if (symname == NULL || *symname == '\0')
c5aa993b 2128 continue; /* probably botched, certainly useless */
c906108c 2129
768a979c
UW
2130 gdbarch = get_objfile_arch (SYMBOL_SYMTAB (sym)->objfile);
2131
c906108c 2132 printf_filtered ("Symbol %s is ", symname);
c5aa993b
JM
2133 switch (SYMBOL_CLASS (sym))
2134 {
2135 default:
2136 case LOC_UNDEF: /* messed up symbol? */
2137 printf_filtered ("a bogus symbol, class %d.\n",
2138 SYMBOL_CLASS (sym));
2139 count--; /* don't count this one */
2140 continue;
2141 case LOC_CONST:
104c1213 2142 printf_filtered ("a constant with value %ld (0x%lx)",
c5aa993b
JM
2143 SYMBOL_VALUE (sym), SYMBOL_VALUE (sym));
2144 break;
2145 case LOC_CONST_BYTES:
2146 printf_filtered ("constant bytes: ");
2147 if (SYMBOL_TYPE (sym))
2148 for (j = 0; j < TYPE_LENGTH (SYMBOL_TYPE (sym)); j++)
2149 fprintf_filtered (gdb_stdout, " %02x",
2150 (unsigned) SYMBOL_VALUE_BYTES (sym)[j]);
2151 break;
2152 case LOC_STATIC:
2153 printf_filtered ("in static storage at address ");
5af949e3
UW
2154 printf_filtered ("%s", paddress (gdbarch,
2155 SYMBOL_VALUE_ADDRESS (sym)));
c5aa993b
JM
2156 break;
2157 case LOC_REGISTER:
768a979c
UW
2158 /* GDBARCH is the architecture associated with the objfile
2159 the symbol is defined in; the target architecture may be
2160 different, and may provide additional registers. However,
2161 we do not know the target architecture at this point.
2162 We assume the objfile architecture will contain all the
2163 standard registers that occur in debug info in that
2164 objfile. */
2165 regno = SYMBOL_REGISTER_OPS (sym)->register_number (sym, gdbarch);
2166
2a2d4dc3
AS
2167 if (SYMBOL_IS_ARGUMENT (sym))
2168 printf_filtered ("an argument in register $%s",
768a979c 2169 gdbarch_register_name (gdbarch, regno));
2a2d4dc3
AS
2170 else
2171 printf_filtered ("a local variable in register $%s",
768a979c 2172 gdbarch_register_name (gdbarch, regno));
c5aa993b
JM
2173 break;
2174 case LOC_ARG:
c5aa993b
JM
2175 printf_filtered ("an argument at stack/frame offset %ld",
2176 SYMBOL_VALUE (sym));
2177 break;
2178 case LOC_LOCAL:
2179 printf_filtered ("a local variable at frame offset %ld",
2180 SYMBOL_VALUE (sym));
2181 break;
2182 case LOC_REF_ARG:
2183 printf_filtered ("a reference argument at offset %ld",
2184 SYMBOL_VALUE (sym));
2185 break;
c5aa993b 2186 case LOC_REGPARM_ADDR:
768a979c
UW
2187 /* Note comment at LOC_REGISTER. */
2188 regno = SYMBOL_REGISTER_OPS (sym)->register_number (sym, gdbarch);
c5aa993b 2189 printf_filtered ("the address of an argument, in register $%s",
768a979c 2190 gdbarch_register_name (gdbarch, regno));
c5aa993b
JM
2191 break;
2192 case LOC_TYPEDEF:
2193 printf_filtered ("a typedef.\n");
2194 continue;
2195 case LOC_LABEL:
2196 printf_filtered ("a label at address ");
5af949e3
UW
2197 printf_filtered ("%s", paddress (gdbarch,
2198 SYMBOL_VALUE_ADDRESS (sym)));
c5aa993b
JM
2199 break;
2200 case LOC_BLOCK:
2201 printf_filtered ("a function at address ");
5af949e3
UW
2202 printf_filtered ("%s",
2203 paddress (gdbarch, BLOCK_START (SYMBOL_BLOCK_VALUE (sym))));
c5aa993b 2204 break;
c5aa993b 2205 case LOC_UNRESOLVED:
3567439c 2206 msym = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (sym),
450bd37b 2207 NULL, NULL);
c5aa993b
JM
2208 if (msym == NULL)
2209 printf_filtered ("Unresolved Static");
2210 else
2211 {
2212 printf_filtered ("static storage at address ");
5af949e3
UW
2213 printf_filtered ("%s",
2214 paddress (gdbarch, SYMBOL_VALUE_ADDRESS (msym)));
c5aa993b
JM
2215 }
2216 break;
2217 case LOC_OPTIMIZED_OUT:
2218 printf_filtered ("optimized out.\n");
2219 continue;
450bd37b 2220 case LOC_COMPUTED:
768a979c 2221 SYMBOL_COMPUTED_OPS (sym)->describe_location (sym, gdb_stdout);
450bd37b 2222 break;
c5aa993b 2223 }
c906108c 2224 if (SYMBOL_TYPE (sym))
c5aa993b 2225 printf_filtered (", length %d.\n",
450bd37b 2226 TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym))));
c906108c
SS
2227 }
2228 if (BLOCK_FUNCTION (block))
2229 break;
2230 else
2231 block = BLOCK_SUPERBLOCK (block);
2232 }
2233 if (count <= 0)
2234 printf_filtered ("Scope for %s contains no locals or arguments.\n",
2235 save_args);
2236}
2237
2238/* worker function (cleanup) */
2239static void
710b33bd 2240replace_comma (void *data)
c906108c 2241{
710b33bd 2242 char *comma = data;
c906108c
SS
2243 *comma = ',';
2244}
2245
2246/* tdump command */
2247static void
fba45db2 2248trace_dump_command (char *args, int from_tty)
c906108c 2249{
515630c5
UW
2250 struct regcache *regcache;
2251 struct gdbarch *gdbarch;
1042e4c0 2252 struct breakpoint *t;
c906108c 2253 struct action_line *action;
c5aa993b
JM
2254 char *action_exp, *next_comma;
2255 struct cleanup *old_cleanups;
2256 int stepping_actions = 0;
2257 int stepping_frame = 0;
9355b391 2258 struct bp_location *loc;
c906108c 2259
c906108c
SS
2260 if (tracepoint_number == -1)
2261 {
8a3fe4f8 2262 warning (_("No current trace frame."));
c906108c
SS
2263 return;
2264 }
2265
1042e4c0 2266 t = get_tracepoint (tracepoint_number);
c906108c
SS
2267
2268 if (t == NULL)
8a3fe4f8 2269 error (_("No known tracepoint matches 'current' tracepoint #%d."),
c906108c
SS
2270 tracepoint_number);
2271
2272 old_cleanups = make_cleanup (null_cleanup, NULL);
2273
c5aa993b 2274 printf_filtered ("Data collected at tracepoint %d, trace frame %d:\n",
c906108c
SS
2275 tracepoint_number, traceframe_number);
2276
2277 /* The current frame is a trap frame if the frame PC is equal
2278 to the tracepoint PC. If not, then the current frame was
2279 collected during single-stepping. */
2280
515630c5
UW
2281 regcache = get_current_regcache ();
2282 gdbarch = get_regcache_arch (regcache);
2283
9355b391
SS
2284 /* If the traceframe's address matches any of the tracepoint's
2285 locations, assume it is a direct hit rather than a while-stepping
2286 frame. (FIXME this is not reliable, should record each frame's
2287 type.) */
2288 stepping_frame = 1;
2289 for (loc = t->loc; loc; loc = loc->next)
2290 if (loc->address == regcache_read_pc (regcache))
2291 stepping_frame = 0;
c906108c
SS
2292
2293 for (action = t->actions; action; action = action->next)
2294 {
2295 struct cmd_list_element *cmd;
2296
c5aa993b 2297 QUIT; /* allow user to bail out with ^C */
c906108c 2298 action_exp = action->action;
104c1213 2299 while (isspace ((int) *action_exp))
c906108c
SS
2300 action_exp++;
2301
2302 /* The collection actions to be done while stepping are
c5aa993b 2303 bracketed by the commands "while-stepping" and "end". */
c906108c
SS
2304
2305 if (*action_exp == '#') /* comment line */
2306 continue;
2307
2308 cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
2309 if (cmd == 0)
8a3fe4f8 2310 error (_("Bad action list item: %s"), action_exp);
c906108c 2311
bbaca940 2312 if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand))
c906108c 2313 stepping_actions = 1;
bbaca940 2314 else if (cmd_cfunc_eq (cmd, end_actions_pseudocommand))
c906108c 2315 stepping_actions = 0;
bbaca940 2316 else if (cmd_cfunc_eq (cmd, collect_pseudocommand))
c906108c
SS
2317 {
2318 /* Display the collected data.
d183932d
MS
2319 For the trap frame, display only what was collected at
2320 the trap. Likewise for stepping frames, display only
2321 what was collected while stepping. This means that the
2322 two boolean variables, STEPPING_FRAME and
2323 STEPPING_ACTIONS should be equal. */
c906108c
SS
2324 if (stepping_frame == stepping_actions)
2325 {
c5aa993b
JM
2326 do
2327 { /* repeat over a comma-separated list */
2328 QUIT; /* allow user to bail out with ^C */
2329 if (*action_exp == ',')
2330 action_exp++;
104c1213 2331 while (isspace ((int) *action_exp))
c5aa993b
JM
2332 action_exp++;
2333
2334 next_comma = strchr (action_exp, ',');
2335
2336 if (0 == strncasecmp (action_exp, "$reg", 4))
2337 registers_info (NULL, from_tty);
2338 else if (0 == strncasecmp (action_exp, "$loc", 4))
2339 locals_info (NULL, from_tty);
2340 else if (0 == strncasecmp (action_exp, "$arg", 4))
2341 args_info (NULL, from_tty);
2342 else
2343 { /* variable */
2344 if (next_comma)
2345 {
2346 make_cleanup (replace_comma, next_comma);
2347 *next_comma = '\0';
2348 }
2349 printf_filtered ("%s = ", action_exp);
2350 output_command (action_exp, from_tty);
2351 printf_filtered ("\n");
2352 }
2353 if (next_comma)
2354 *next_comma = ',';
2355 action_exp = next_comma;
2356 }
2357 while (action_exp && *action_exp == ',');
c906108c
SS
2358 }
2359 }
2360 }
2361 discard_cleanups (old_cleanups);
2362}
2363
00bf0b85
SS
2364extern int trace_regblock_size;
2365
2366static void
2367trace_save_command (char *args, int from_tty)
2368{
2369 char **argv;
2370 char *filename = NULL, *pathname;
2371 int target_does_save = 0;
2372 struct cleanup *cleanup;
2373 struct trace_status *ts = current_trace_status ();
2374 int err, status;
2375 FILE *fp;
2376 struct uploaded_tp *uploaded_tps = NULL, *utp;
2377 struct uploaded_tsv *uploaded_tsvs = NULL, *utsv;
2378 int a;
2379 LONGEST gotten = 0;
2380 ULONGEST offset = 0;
2381#define MAX_TRACE_UPLOAD 2000
2382 gdb_byte buf[MAX_TRACE_UPLOAD];
98e03262 2383 int written;
00bf0b85
SS
2384
2385 if (args == NULL)
2386 error_no_arg (_("file in which to save trace data"));
2387
2388 argv = gdb_buildargv (args);
2389 make_cleanup_freeargv (argv);
2390
2391 for (; *argv; ++argv)
2392 {
2393 if (strcmp (*argv, "-r") == 0)
2394 target_does_save = 1;
2395 else if (**argv == '-')
2396 error (_("unknown option `%s'"), *argv);
2397 else
2398 filename = *argv;
2399 }
2400
2401 if (!filename)
2402 error_no_arg (_("file in which to save trace data"));
2403
2404 /* If the target is to save the data to a file on its own, then just
2405 send the command and be done with it. */
2406 if (target_does_save)
2407 {
2408 err = target_save_trace_data (filename);
2409 if (err < 0)
2410 error (_("Target failed to save trace data to '%s'."),
2411 filename);
2412 return;
2413 }
2414
2415 /* Get the trace status first before opening the file, so if the
2416 target is losing, we can get out without touching files. */
2417 status = target_get_trace_status (ts);
2418
2419 pathname = tilde_expand (args);
2420 cleanup = make_cleanup (xfree, pathname);
2421
2422 fp = fopen (pathname, "w");
2423 if (!fp)
2424 error (_("Unable to open file '%s' for saving trace data (%s)"),
2425 args, safe_strerror (errno));
2426 make_cleanup_fclose (fp);
2427
2428 /* Write a file header, with a high-bit-set char to indicate a
2429 binary file, plus a hint as what this file is, and a version
2430 number in case of future needs. */
98e03262
SS
2431 written = fwrite ("\x7fTRACE0\n", 8, 1, fp);
2432 if (written < 8)
2433 perror_with_name (pathname);
00bf0b85
SS
2434
2435 /* Write descriptive info. */
2436
2437 /* Write out the size of a register block. */
2438 fprintf (fp, "R %x\n", trace_regblock_size);
2439
2440 /* Write out status of the tracing run (aka "tstatus" info). */
98e03262 2441 fprintf (fp, "status %c;%s:%x;tframes:%x;tfree:%llx\n",
00bf0b85
SS
2442 (ts->running ? '1' : '0'),
2443 stop_reason_names[ts->stop_reason], ts->stopping_tracepoint,
98e03262 2444 ts->traceframe_count, ts->buffer_free);
00bf0b85
SS
2445
2446 /* Note that we want to upload tracepoints and save those, rather
2447 than simply writing out the local ones, because the user may have
2448 changed tracepoints in GDB in preparation for a future tracing
2449 run, or maybe just mass-deleted all types of breakpoints as part
2450 of cleaning up. So as not to contaminate the session, leave the
2451 data in its uploaded form, don't make into real tracepoints. */
2452
2453 /* Get trace state variables first, they may be checked when parsing
2454 uploaded commands. */
2455
2456 target_upload_trace_state_variables (&uploaded_tsvs);
2457
2458 for (utsv = uploaded_tsvs; utsv; utsv = utsv->next)
2459 {
2460 char *buf = "";
2461
2462 if (utsv->name)
2463 {
2464 buf = (char *) xmalloc (strlen (utsv->name) * 2 + 1);
2465 bin2hex ((gdb_byte *) (utsv->name), buf, 0);
2466 }
2467
2468 fprintf (fp, "tsv %x:%s:%x:%s\n",
2469 utsv->number, phex_nz (utsv->initial_value, 8),
2470 utsv->builtin, buf);
2471
2472 if (utsv->name)
2473 xfree (buf);
2474 }
2475
2476 free_uploaded_tsvs (&uploaded_tsvs);
2477
2478 target_upload_tracepoints (&uploaded_tps);
2479
2480 for (utp = uploaded_tps; utp; utp = utp->next)
2481 {
2482 fprintf (fp, "tp T%x:%s:%c:%x:%x",
2483 utp->number, phex_nz (utp->addr, sizeof (utp->addr)),
2484 (utp->enabled ? 'E' : 'D'), utp->step, utp->pass);
2485 if (utp->type == bp_fast_tracepoint)
2486 fprintf (fp, ":F%x", utp->orig_size);
2487 if (utp->cond)
2488 fprintf (fp, ":X%x,%s", (unsigned int) strlen (utp->cond) / 2,
2489 utp->cond);
2490 fprintf (fp, "\n");
2491 for (a = 0; a < utp->numactions; ++a)
2492 fprintf (fp, "tp A%x:%s:%s\n",
2493 utp->number, phex_nz (utp->addr, sizeof (utp->addr)),
2494 utp->actions[a]);
2495 for (a = 0; a < utp->num_step_actions; ++a)
2496 fprintf (fp, "tp S%x:%s:%s\n",
2497 utp->number, phex_nz (utp->addr, sizeof (utp->addr)),
2498 utp->step_actions[a]);
2499 }
2500
2501 free_uploaded_tps (&uploaded_tps);
2502
2503 /* Mark the end of the definition section. */
2504 fprintf (fp, "\n");
2505
2506 /* Get and write the trace data proper. We ask for big blocks, in
2507 the hopes of efficiency, but will take less if the target has
2508 packet size limitations or some such. */
2509 while (1)
2510 {
2511 gotten = target_get_raw_trace_data (buf, offset, MAX_TRACE_UPLOAD);
2512 if (gotten < 0)
2513 error (_("Failure to get requested trace buffer data"));
2514 /* No more data is forthcoming, we're done. */
2515 if (gotten == 0)
2516 break;
98e03262
SS
2517 written = fwrite (buf, gotten, 1, fp);
2518 if (written < gotten)
2519 perror_with_name (pathname);
00bf0b85
SS
2520 offset += gotten;
2521 }
2522
2523 /* Mark the end of trace data. */
98e03262
SS
2524 written = fwrite (&gotten, 4, 1, fp);
2525 if (written < 4)
2526 perror_with_name (pathname);
00bf0b85
SS
2527
2528 do_cleanups (cleanup);
2529 if (from_tty)
2530 printf_filtered (_("Trace data saved to file '%s'.\n"), args);
2531}
2532
d5551862
SS
2533/* Tell the target what to do with an ongoing tracing run if GDB
2534 disconnects for some reason. */
2535
2536void
2537send_disconnected_tracing_value (int value)
2538{
35b1e5cc 2539 target_set_disconnected_tracing (value);
d5551862
SS
2540}
2541
2542static void
2543set_disconnected_tracing (char *args, int from_tty,
2544 struct cmd_list_element *c)
2545{
2546 send_disconnected_tracing_value (disconnected_tracing);
2547}
2548
c906108c
SS
2549/* Convert the memory pointed to by mem into hex, placing result in buf.
2550 * Return a pointer to the last char put in buf (null)
2551 * "stolen" from sparc-stub.c
2552 */
2553
c5aa993b 2554static const char hexchars[] = "0123456789abcdef";
c906108c 2555
47b667de
AC
2556static char *
2557mem2hex (gdb_byte *mem, char *buf, int count)
c906108c 2558{
47b667de 2559 gdb_byte ch;
c906108c
SS
2560
2561 while (count-- > 0)
2562 {
2563 ch = *mem++;
2564
2565 *buf++ = hexchars[ch >> 4];
2566 *buf++ = hexchars[ch & 0xf];
2567 }
2568
2569 *buf = 0;
2570
2571 return buf;
2572}
2573
c5aa993b 2574int
fba45db2 2575get_traceframe_number (void)
c906108c 2576{
c5aa993b 2577 return traceframe_number;
c906108c
SS
2578}
2579
06cd862c
PA
2580/* Make the traceframe NUM be the current trace frame. Does nothing
2581 if NUM is already current. */
2582
2583void
2584set_traceframe_number (int num)
2585{
2586 int newnum;
2587
2588 if (traceframe_number == num)
2589 {
2590 /* Nothing to do. */
2591 return;
2592 }
2593
2594 newnum = target_trace_find (tfind_number, num, 0, 0, NULL);
2595
2596 if (newnum != num)
2597 warning (_("could not change traceframe"));
2598
2599 traceframe_number = newnum;
2600
2601 /* Changing the traceframe changes our view of registers and of the
2602 frame chain. */
2603 registers_changed ();
2604}
2605
2606/* A cleanup used when switching away and back from tfind mode. */
2607
2608struct current_traceframe_cleanup
2609{
2610 /* The traceframe we were inspecting. */
2611 int traceframe_number;
2612};
2613
2614static void
2615do_restore_current_traceframe_cleanup (void *arg)
2616{
2617 struct current_traceframe_cleanup *old = arg;
2618
2619 set_traceframe_number (old->traceframe_number);
2620}
2621
2622static void
2623restore_current_traceframe_cleanup_dtor (void *arg)
2624{
2625 struct current_traceframe_cleanup *old = arg;
2626
2627 xfree (old);
2628}
2629
2630struct cleanup *
2631make_cleanup_restore_current_traceframe (void)
2632{
2633 struct current_traceframe_cleanup *old;
2634
2635 old = xmalloc (sizeof (struct current_traceframe_cleanup));
2636 old->traceframe_number = traceframe_number;
2637
2638 return make_cleanup_dtor (do_restore_current_traceframe_cleanup, old,
2639 restore_current_traceframe_cleanup_dtor);
2640}
00bf0b85
SS
2641
2642/* Given a number and address, return an uploaded tracepoint with that
2643 number, creating if necessary. */
2644
2645struct uploaded_tp *
2646get_uploaded_tp (int num, ULONGEST addr, struct uploaded_tp **utpp)
2647{
2648 struct uploaded_tp *utp;
2649
2650 for (utp = *utpp; utp; utp = utp->next)
2651 if (utp->number == num && utp->addr == addr)
2652 return utp;
2653 utp = (struct uploaded_tp *) xmalloc (sizeof (struct uploaded_tp));
2654 memset (utp, 0, sizeof (struct uploaded_tp));
2655 utp->number = num;
2656 utp->addr = addr;
2657 utp->next = *utpp;
2658 *utpp = utp;
2659 return utp;
2660}
2661
2662static void
2663free_uploaded_tps (struct uploaded_tp **utpp)
2664{
2665 struct uploaded_tp *next_one;
2666
2667 while (*utpp)
2668 {
2669 next_one = (*utpp)->next;
2670 xfree (*utpp);
2671 *utpp = next_one;
2672 }
2673}
2674
2675/* Given a number and address, return an uploaded tracepoint with that
2676 number, creating if necessary. */
2677
2678struct uploaded_tsv *
2679get_uploaded_tsv (int num, struct uploaded_tsv **utsvp)
2680{
2681 struct uploaded_tsv *utsv;
2682
2683 for (utsv = *utsvp; utsv; utsv = utsv->next)
2684 if (utsv->number == num)
2685 return utsv;
2686 utsv = (struct uploaded_tsv *) xmalloc (sizeof (struct uploaded_tsv));
2687 memset (utsv, 0, sizeof (struct uploaded_tsv));
2688 utsv->number = num;
2689 utsv->next = *utsvp;
2690 *utsvp = utsv;
2691 return utsv;
2692}
2693
2694static void
2695free_uploaded_tsvs (struct uploaded_tsv **utsvp)
2696{
2697 struct uploaded_tsv *next_one;
2698
2699 while (*utsvp)
2700 {
2701 next_one = (*utsvp)->next;
2702 xfree (*utsvp);
2703 *utsvp = next_one;
2704 }
2705}
2706
2707/* Look for an existing tracepoint that seems similar enough to the
2708 uploaded one. Enablement isn't compared, because the user can
2709 toggle that freely, and may have done so in anticipation of the
2710 next trace run. */
2711
2712struct breakpoint *
2713find_matching_tracepoint (struct uploaded_tp *utp)
2714{
2715 VEC(breakpoint_p) *tp_vec = all_tracepoints ();
2716 int ix;
2717 struct breakpoint *t;
2718 struct bp_location *loc;
2719
2720 for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, t); ix++)
2721 {
2722 if (t->type == utp->type
2723 && t->step_count == utp->step
2724 && t->pass_count == utp->pass
2725 /* FIXME also test conditionals and actions */
2726 )
2727 {
2728 /* Scan the locations for an address match. */
2729 for (loc = t->loc; loc; loc = loc->next)
2730 {
2731 if (loc->address == utp->addr)
2732 return t;
2733 }
2734 }
2735 }
2736 return NULL;
2737}
2738
2739/* Given a list of tracepoints uploaded from a target, attempt to
2740 match them up with existing tracepoints, and create new ones if not
2741 found. */
2742
2743void
2744merge_uploaded_tracepoints (struct uploaded_tp **uploaded_tps)
2745{
2746 struct uploaded_tp *utp;
2747 struct breakpoint *t;
2748
2749 /* Look for GDB tracepoints that match up with our uploaded versions. */
2750 for (utp = *uploaded_tps; utp; utp = utp->next)
2751 {
2752 t = find_matching_tracepoint (utp);
2753 if (t)
2754 printf_filtered (_("Assuming tracepoint %d is same as target's tracepoint %d at %s.\n"),
2755 t->number, utp->number, paddress (get_current_arch (), utp->addr));
2756 else
2757 {
2758 t = create_tracepoint_from_upload (utp);
2759 if (t)
2760 printf_filtered (_("Created tracepoint %d for target's tracepoint %d at %s.\n"),
2761 t->number, utp->number, paddress (get_current_arch (), utp->addr));
2762 else
2763 printf_filtered (_("Failed to create tracepoint for target's tracepoint %d at %s, skipping it.\n"),
2764 utp->number, paddress (get_current_arch (), utp->addr));
2765 }
2766 /* Whether found or created, record the number used by the
2767 target, to help with mapping target tracepoints back to their
2768 counterparts here. */
2769 if (t)
2770 t->number_on_target = utp->number;
2771 }
2772
2773 free_uploaded_tps (uploaded_tps);
2774}
2775
2776/* Trace state variables don't have much to identify them beyond their
2777 name, so just use that to detect matches. */
2778
2779struct trace_state_variable *
2780find_matching_tsv (struct uploaded_tsv *utsv)
2781{
2782 if (!utsv->name)
2783 return NULL;
2784
2785 return find_trace_state_variable (utsv->name);
2786}
2787
2788struct trace_state_variable *
2789create_tsv_from_upload (struct uploaded_tsv *utsv)
2790{
2791 const char *namebase;
2792 char buf[20];
2793 int try_num = 0;
2794 struct trace_state_variable *tsv;
2795
2796 if (utsv->name)
2797 {
2798 namebase = utsv->name;
2799 sprintf (buf, "%s", namebase);
2800 }
2801 else
2802 {
2803 namebase = "__tsv";
2804 sprintf (buf, "%s_%d", namebase, try_num++);
2805 }
2806
2807 /* Fish for a name that is not in use. */
2808 /* (should check against all internal vars?) */
2809 while (find_trace_state_variable (buf))
2810 sprintf (buf, "%s_%d", namebase, try_num++);
2811
2812 /* We have an available name, create the variable. */
2813 tsv = create_trace_state_variable (xstrdup (buf));
2814 tsv->initial_value = utsv->initial_value;
2815 tsv->builtin = utsv->builtin;
2816
2817 return tsv;
2818}
2819
2820/* Given a list of uploaded trace state variables, try to match them
2821 up with existing variables, or create additional ones. */
2822
2823void
2824merge_uploaded_trace_state_variables (struct uploaded_tsv **uploaded_tsvs)
2825{
2826 int ix;
2827 struct uploaded_tsv *utsv;
2828 struct trace_state_variable *tsv;
2829 int highest;
2830
2831 /* Most likely some numbers will have to be reassigned as part of
2832 the merge, so clear them all in anticipation. */
2833 for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
2834 tsv->number = 0;
2835
2836 for (utsv = *uploaded_tsvs; utsv; utsv = utsv->next)
2837 {
2838 tsv = find_matching_tsv (utsv);
2839 if (tsv)
2840 printf_filtered (_("Assuming trace state variable $%s is same as target's variable %d.\n"),
2841 tsv->name, utsv->number);
2842 else
2843 {
2844 tsv = create_tsv_from_upload (utsv);
2845 printf_filtered (_("Created trace state variable $%s for target's variable %d.\n"),
2846 tsv->name, utsv->number);
2847 }
2848 /* Give precedence to numberings that come from the target. */
2849 if (tsv)
2850 tsv->number = utsv->number;
2851 }
2852
2853 /* Renumber everything that didn't get a target-assigned number. */
2854 highest = 0;
2855 for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
2856 if (tsv->number > highest)
2857 highest = tsv->number;
2858
2859 ++highest;
2860 for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
2861 if (tsv->number == 0)
2862 tsv->number = highest++;
2863
2864 free_uploaded_tsvs (uploaded_tsvs);
2865}
2866
2867/* target tfile command */
2868
2869struct target_ops tfile_ops;
2870
2871/* Fill in tfile_ops with its defined operations and properties. */
2872
2873#define TRACE_HEADER_SIZE 8
2874
98e03262 2875char *trace_filename;
00bf0b85
SS
2876int trace_fd = -1;
2877off_t trace_frames_offset;
2878off_t cur_offset;
2879int cur_data_size;
2880int trace_regblock_size;
2881
2882static void tfile_interp_line (char *line,
2883 struct uploaded_tp **utpp,
2884 struct uploaded_tsv **utsvp);
2885
2886static void
2887tfile_open (char *filename, int from_tty)
2888{
2889 char *temp;
2890 struct cleanup *old_chain;
2891 int flags;
2892 int scratch_chan;
2893 char header[TRACE_HEADER_SIZE];
2894 char linebuf[1000]; /* should be max remote packet size or so */
2895 char byte;
98e03262 2896 int bytes, i, gotten;
00bf0b85
SS
2897 struct trace_status *ts;
2898 struct uploaded_tp *uploaded_tps = NULL;
2899 struct uploaded_tsv *uploaded_tsvs = NULL;
2900
2901 target_preopen (from_tty);
2902 if (!filename)
2903 error (_("No trace file specified."));
2904
2905 filename = tilde_expand (filename);
2906 if (!IS_ABSOLUTE_PATH(filename))
2907 {
2908 temp = concat (current_directory, "/", filename, (char *)NULL);
2909 xfree (filename);
2910 filename = temp;
2911 }
2912
2913 old_chain = make_cleanup (xfree, filename);
2914
2915 flags = O_BINARY | O_LARGEFILE;
2916 flags |= O_RDONLY;
2917 scratch_chan = open (filename, flags, 0);
2918 if (scratch_chan < 0)
2919 perror_with_name (filename);
2920
2921 /* Looks semi-reasonable. Toss the old trace file and work on the new. */
2922
2923 discard_cleanups (old_chain); /* Don't free filename any more */
2924 unpush_target (&tfile_ops);
2925
2926 push_target (&tfile_ops);
00bf0b85 2927
98e03262 2928 trace_filename = xstrdup (filename);
00bf0b85
SS
2929 trace_fd = scratch_chan;
2930
2931 bytes = 0;
2932 /* Read the file header and test for validity. */
98e03262
SS
2933 gotten = read (trace_fd, &header, TRACE_HEADER_SIZE);
2934 if (gotten < 0)
2935 perror_with_name (trace_filename);
2936 else if (gotten < TRACE_HEADER_SIZE)
2937 error (_("Premature end of file while reading trace file"));
2938
00bf0b85
SS
2939 bytes += TRACE_HEADER_SIZE;
2940 if (!(header[0] == 0x7f
2941 && (strncmp (header + 1, "TRACE0\n", 7) == 0)))
2942 error (_("File is not a valid trace file."));
2943
2944 trace_regblock_size = 0;
2945 ts = current_trace_status ();
2946 /* We know we're working with a file. */
2947 ts->from_file = 1;
2948 /* Set defaults in case there is no status line. */
2949 ts->running_known = 0;
2950 ts->stop_reason = trace_stop_reason_unknown;
2951 ts->traceframe_count = -1;
2952 ts->buffer_free = 0;
2953
2954 /* Read through a section of newline-terminated lines that
2955 define things like tracepoints. */
2956 i = 0;
2957 while (1)
2958 {
98e03262
SS
2959 gotten = read (trace_fd, &byte, 1);
2960 if (gotten < 0)
2961 perror_with_name (trace_filename);
2962 else if (gotten < 1)
2963 error (_("Premature end of file while reading trace file"));
2964
00bf0b85
SS
2965 ++bytes;
2966 if (byte == '\n')
2967 {
2968 /* Empty line marks end of the definition section. */
2969 if (i == 0)
2970 break;
2971 linebuf[i] = '\0';
2972 i = 0;
2973 tfile_interp_line (linebuf, &uploaded_tps, &uploaded_tsvs);
2974 }
2975 else
2976 linebuf[i++] = byte;
2977 if (i >= 1000)
2978 error (_("Excessively long lines in trace file"));
2979 }
2980
2981 /* Add the file's tracepoints and variables into the current mix. */
2982
10ef8d6a
PA
2983 /* Get trace state variables first, they may be checked when parsing
2984 uploaded commands. */
00bf0b85
SS
2985 merge_uploaded_trace_state_variables (&uploaded_tsvs);
2986
10ef8d6a
PA
2987 merge_uploaded_tracepoints (&uploaded_tps);
2988
00bf0b85
SS
2989 /* Record the starting offset of the binary trace data. */
2990 trace_frames_offset = bytes;
2991
2992 /* If we don't have a blocksize, we can't interpret the
2993 traceframes. */
2994 if (trace_regblock_size == 0)
2995 error (_("No register block size recorded in trace file"));
2996 if (ts->traceframe_count <= 0)
2997 {
2998 warning ("No traceframes present in this file.");
2999 return;
3000 }
3001
3002#define TFILE_PID (1)
3003 inferior_appeared (current_inferior (), TFILE_PID);
3004 inferior_ptid = pid_to_ptid (TFILE_PID);
3005 add_thread_silent (inferior_ptid);
3006
3007 post_create_inferior (&tfile_ops, from_tty);
3008
3009#if 0
3010 /* FIXME this will get defined in MI patch submission */
3011 tfind_1 (tfind_number, 0, 0, 0, 0);
3012#endif
3013}
3014
3015/* Interpret the given line from the definitions part of the trace
3016 file. */
3017
3018static void
3019tfile_interp_line (char *line,
3020 struct uploaded_tp **utpp, struct uploaded_tsv **utsvp)
3021{
3022 char *p = line;
3023
3024 if (strncmp (p, "R ", strlen ("R ")) == 0)
3025 {
3026 p += strlen ("R ");
3027 trace_regblock_size = strtol (p, &p, 16);
3028 }
3029 else if (strncmp (p, "status ", strlen ("status ")) == 0)
3030 {
3031 p += strlen ("status ");
3032 parse_trace_status (p, current_trace_status ());
3033 }
3034 else if (strncmp (p, "tp ", strlen ("tp ")) == 0)
3035 {
3036 p += strlen ("tp ");
3037 parse_tracepoint_definition (p, utpp);
3038 }
3039 else if (strncmp (p, "tsv ", strlen ("tsv ")) == 0)
3040 {
3041 p += strlen ("tsv ");
3042 parse_tsv_definition (p, utsvp);
3043 }
3044 else
3045 warning ("Ignoring trace file definition \"%s\"", line);
3046}
3047
3048/* Parse the part of trace status syntax that is shared between
3049 the remote protocol and the trace file reader. */
3050
3051extern char *unpack_varlen_hex (char *buff, ULONGEST *result);
3052
3053void
3054parse_trace_status (char *line, struct trace_status *ts)
3055{
3056 char *p = line, *p1, *p_temp;
3057 ULONGEST val;
3058
3059 ts->running_known = 1;
3060 ts->running = (*p++ == '1');
3061 ts->stop_reason = trace_stop_reason_unknown;
3062 while (*p++)
3063 {
3064 p1 = strchr (p, ':');
3065 if (p1 == NULL)
3066 error (_("Malformed trace status, at %s\n\
3067Status line: '%s'\n"), p, line);
3068 if (strncmp (p, stop_reason_names[trace_buffer_full], p1 - p) == 0)
3069 {
3070 p = unpack_varlen_hex (++p1, &val);
3071 ts->stop_reason = trace_buffer_full;
3072 }
3073 else if (strncmp (p, stop_reason_names[trace_never_run], p1 - p) == 0)
3074 {
3075 p = unpack_varlen_hex (++p1, &val);
3076 ts->stop_reason = trace_never_run;
3077 }
3078 else if (strncmp (p, stop_reason_names[tracepoint_passcount], p1 - p) == 0)
3079 {
3080 p = unpack_varlen_hex (++p1, &val);
3081 ts->stop_reason = tracepoint_passcount;
3082 ts->stopping_tracepoint = val;
3083 }
3084 else if (strncmp (p, stop_reason_names[tstop_command], p1 - p) == 0)
3085 {
3086 p = unpack_varlen_hex (++p1, &val);
3087 ts->stop_reason = tstop_command;
3088 }
3089 if (strncmp (p, "tframes", p1 - p) == 0)
3090 {
3091 p = unpack_varlen_hex (++p1, &val);
3092 ts->traceframe_count = val;
3093 }
3094 if (strncmp (p, "tfree", p1 - p) == 0)
3095 {
3096 p = unpack_varlen_hex (++p1, &val);
3097 ts->buffer_free = val;
3098 }
3099 else
3100 {
3101 /* Silently skip unknown optional info. */
3102 p_temp = strchr (p1 + 1, ';');
3103 if (p_temp)
3104 p = p_temp;
3105 else
3106 /* Must be at the end. */
3107 break;
3108 }
3109 }
3110}
3111
3112/* Given a line of text defining a tracepoint or tracepoint action, parse
3113 it into an "uploaded tracepoint". */
3114
3115void
3116parse_tracepoint_definition (char *line, struct uploaded_tp **utpp)
3117{
3118 char *p;
3119 char piece;
3120 ULONGEST num, addr, step, pass, orig_size, xlen;
3121 int enabled, i;
3122 enum bptype type;
3123 char *cond;
3124 struct uploaded_tp *utp = NULL;
3125
3126 p = line;
3127 /* Both tracepoint and action definitions start with the same number
3128 and address sequence. */
3129 piece = *p++;
3130 p = unpack_varlen_hex (p, &num);
3131 p++; /* skip a colon */
3132 p = unpack_varlen_hex (p, &addr);
3133 p++; /* skip a colon */
3134 if (piece == 'T')
3135 {
3136 enabled = (*p++ == 'E');
3137 p++; /* skip a colon */
3138 p = unpack_varlen_hex (p, &step);
3139 p++; /* skip a colon */
3140 p = unpack_varlen_hex (p, &pass);
3141 type = bp_tracepoint;
3142 cond = NULL;
3143 /* Thumb through optional fields. */
3144 while (*p == ':')
3145 {
3146 p++; /* skip a colon */
3147 if (*p == 'F')
3148 {
3149 type = bp_fast_tracepoint;
3150 p++;
3151 p = unpack_varlen_hex (p, &orig_size);
3152 }
3153 else if (*p == 'X')
3154 {
3155 p++;
3156 p = unpack_varlen_hex (p, &xlen);
3157 p++; /* skip a comma */
3158 cond = (char *) xmalloc (2 * xlen + 1);
3159 strncpy (cond, p, 2 * xlen);
3160 cond[2 * xlen] = '\0';
3161 p += 2 * xlen;
3162 }
3163 else
3164 warning ("Unrecognized char '%c' in tracepoint definition, skipping rest", *p);
3165 }
3166 utp = get_uploaded_tp (num, addr, utpp);
3167 utp->type = type;
3168 utp->enabled = enabled;
3169 utp->step = step;
3170 utp->pass = pass;
3171 utp->cond = cond;
3172 }
3173 else if (piece == 'A')
3174 {
3175 utp = get_uploaded_tp (num, addr, utpp);
3176 utp->actions[utp->numactions++] = xstrdup (p);
3177 }
3178 else if (piece == 'S')
3179 {
3180 utp = get_uploaded_tp (num, addr, utpp);
3181 utp->step_actions[utp->num_step_actions++] = xstrdup (p);
3182 }
3183 else
3184 {
3185 error ("Invalid tracepoint piece");
3186 }
3187}
3188
3189/* Convert a textual description of a trace state variable into an
3190 uploaded object. */
3191
3192void
3193parse_tsv_definition (char *line, struct uploaded_tsv **utsvp)
3194{
3195 char *p, *buf;
3196 ULONGEST num, initval, builtin;
3197 int end;
3198 struct uploaded_tsv *utsv = NULL;
3199
3200 buf = alloca (strlen (line));
3201
3202 p = line;
3203 p = unpack_varlen_hex (p, &num);
3204 p++; /* skip a colon */
3205 p = unpack_varlen_hex (p, &initval);
3206 p++; /* skip a colon */
3207 p = unpack_varlen_hex (p, &builtin);
3208 p++; /* skip a colon */
3209 end = hex2bin (p, (gdb_byte *) buf, strlen (p) / 2);
3210 buf[end] = '\0';
3211
3212 utsv = get_uploaded_tsv (num, utsvp);
3213 utsv->initial_value = initval;
3214 utsv->builtin = builtin;
3215 utsv->name = xstrdup (buf);
3216}
3217
3218/* Close the trace file and generally clean up. */
3219
3220static void
3221tfile_close (int quitting)
3222{
3223 int pid;
3224
3225 if (trace_fd < 0)
3226 return;
3227
3228 pid = ptid_get_pid (inferior_ptid);
3229 inferior_ptid = null_ptid; /* Avoid confusion from thread stuff */
3230 exit_inferior_silent (pid);
3231
3232 close (trace_fd);
3233 trace_fd = -1;
98e03262
SS
3234 if (trace_filename)
3235 xfree (trace_filename);
00bf0b85
SS
3236}
3237
3238static void
3239tfile_files_info (struct target_ops *t)
3240{
3241 /* (it would be useful to mention the name of the file) */
3242 printf_filtered ("Looking at a trace file.\n");
3243}
3244
3245/* The trace status for a file is that tracing can never be run. */
3246
3247static int
3248tfile_get_trace_status (struct trace_status *ts)
3249{
3250 /* Other bits of trace status were collected as part of opening the
3251 trace files, so nothing to do here. */
3252
3253 return -1;
3254}
3255
3256/* Given the position of a traceframe in the file, figure out what
3257 address the frame was collected at. This would normally be the
3258 value of a collected PC register, but if not available, we
3259 improvise. */
3260
3261static ULONGEST
3262tfile_get_traceframe_address (off_t tframe_offset)
3263{
3264 ULONGEST addr = 0;
3265 short tpnum;
3266 struct breakpoint *tp;
3267 off_t saved_offset = cur_offset;
98e03262 3268 int gotten;
00bf0b85
SS
3269
3270 /* FIXME dig pc out of collected registers */
3271
3272 /* Fall back to using tracepoint address. */
3273 lseek (trace_fd, tframe_offset, SEEK_SET);
98e03262
SS
3274 gotten = read (trace_fd, &tpnum, 2);
3275 if (gotten < 0)
3276 perror_with_name (trace_filename);
3277 else if (gotten < 2)
3278 error (_("Premature end of file while reading trace file"));
3279
00bf0b85 3280 tp = get_tracepoint_by_number_on_target (tpnum);
9355b391 3281 /* FIXME this is a poor heuristic if multiple locations */
00bf0b85
SS
3282 if (tp && tp->loc)
3283 addr = tp->loc->address;
3284
3285 /* Restore our seek position. */
3286 cur_offset = saved_offset;
3287 lseek (trace_fd, cur_offset, SEEK_SET);
3288 return addr;
3289}
3290
3291/* Given a type of search and some parameters, scan the collection of
3292 traceframes in the file looking for a match. When found, return
3293 both the traceframe and tracepoint number, otherwise -1 for
3294 each. */
3295
3296static int
3297tfile_trace_find (enum trace_find_type type, int num,
3298 ULONGEST addr1, ULONGEST addr2, int *tpp)
3299{
3300 short tpnum;
98e03262 3301 int tfnum = 0, found = 0, gotten;
00bf0b85
SS
3302 int data_size;
3303 struct breakpoint *tp;
3304 off_t offset, tframe_offset;
3305 ULONGEST tfaddr;
3306
3307 lseek (trace_fd, trace_frames_offset, SEEK_SET);
3308 offset = trace_frames_offset;
3309 while (1)
3310 {
3311 tframe_offset = offset;
98e03262
SS
3312 gotten = read (trace_fd, &tpnum, 2);
3313 if (gotten < 0)
3314 perror_with_name (trace_filename);
3315 else if (gotten < 2)
3316 error (_("Premature end of file while reading trace file"));
00bf0b85
SS
3317 offset += 2;
3318 if (tpnum == 0)
3319 break;
98e03262
SS
3320 gotten = read (trace_fd, &data_size, 4);
3321 if (gotten < 0)
3322 perror_with_name (trace_filename);
3323 else if (gotten < 4)
3324 error (_("Premature end of file while reading trace file"));
00bf0b85
SS
3325 offset += 4;
3326 switch (type)
3327 {
3328 case tfind_number:
3329 if (tfnum == num)
3330 found = 1;
3331 break;
3332 case tfind_pc:
3333 tfaddr = tfile_get_traceframe_address (tframe_offset);
3334 if (tfaddr == addr1)
3335 found = 1;
3336 break;
3337 case tfind_tp:
3338 tp = get_tracepoint (num);
3339 if (tp && tpnum == tp->number_on_target)
3340 found = 1;
3341 break;
3342 case tfind_range:
3343 tfaddr = tfile_get_traceframe_address (tframe_offset);
3344 if (addr1 <= tfaddr && tfaddr <= addr2)
3345 found = 1;
3346 break;
3347 case tfind_outside:
3348 tfaddr = tfile_get_traceframe_address (tframe_offset);
3349 if (!(addr1 <= tfaddr && tfaddr <= addr2))
3350 found = 1;
3351 break;
3352 default:
3353 internal_error (__FILE__, __LINE__, _("unknown tfind type"));
3354 }
3355 if (found)
3356 {
3357 printf_filtered ("Found traceframe %d.\n", tfnum);
3358 if (tpp)
3359 *tpp = tpnum;
3360 cur_offset = offset;
3361 cur_data_size = data_size;
3362 return tfnum;
3363 }
3364 /* Skip past the traceframe's data. */
3365 lseek (trace_fd, data_size, SEEK_CUR);
3366 offset += data_size;
3367 /* Update our own count of traceframes. */
3368 ++tfnum;
3369 }
3370 /* Did not find what we were looking for. */
3371 if (tpp)
3372 *tpp = -1;
3373 return -1;
3374}
3375
3376/* Look for a block of saved registers in the traceframe, and get the
3377 requested register from it. */
3378
3379static void
3380tfile_fetch_registers (struct target_ops *ops,
3381 struct regcache *regcache, int regno)
3382{
3383 struct gdbarch *gdbarch = get_regcache_arch (regcache);
3384 char block_type;
98e03262 3385 int i, pos, offset, regn, regsize, gotten;
00bf0b85
SS
3386 unsigned short mlen;
3387 char *regs;
3388
3389 /* An uninitialized reg size says we're not going to be
3390 successful at getting register blocks. */
3391 if (!trace_regblock_size)
3392 return;
3393
3394 regs = alloca (trace_regblock_size);
3395
3396 lseek (trace_fd, cur_offset, SEEK_SET);
3397 pos = 0;
3398 while (pos < cur_data_size)
3399 {
98e03262
SS
3400 gotten = read (trace_fd, &block_type, 1);
3401 if (gotten < 0)
3402 perror_with_name (trace_filename);
3403 else if (gotten < 1)
3404 error (_("Premature end of file while reading trace file"));
3405
00bf0b85
SS
3406 ++pos;
3407 switch (block_type)
3408 {
3409 case 'R':
98e03262
SS
3410 gotten = read (trace_fd, regs, trace_regblock_size);
3411 if (gotten < 0)
3412 perror_with_name (trace_filename);
3413 else if (gotten < trace_regblock_size)
3414 error (_("Premature end of file while reading trace file"));
3415
00bf0b85
SS
3416 /* Assume the block is laid out in GDB register number order,
3417 each register with the size that it has in GDB. */
3418 offset = 0;
3419 for (regn = 0; regn < gdbarch_num_regs (gdbarch); regn++)
3420 {
3421 regsize = register_size (gdbarch, regn);
3422 /* Make sure we stay within block bounds. */
3423 if (offset + regsize >= trace_regblock_size)
3424 break;
3425 if (!regcache_valid_p (regcache, regn))
3426 {
3427 if (regno == regn)
3428 {
3429 regcache_raw_supply (regcache, regno, regs + offset);
3430 break;
3431 }
3432 else if (regno == -1)
3433 {
3434 regcache_raw_supply (regcache, regn, regs + offset);
3435 }
3436 }
3437 offset += regsize;
3438 }
3439 return;
3440 case 'M':
3441 lseek (trace_fd, 8, SEEK_CUR);
98e03262
SS
3442 gotten = read (trace_fd, &mlen, 2);
3443 if (gotten < 0)
3444 perror_with_name (trace_filename);
3445 else if (gotten < 2)
3446 error (_("Premature end of file while reading trace file"));
00bf0b85
SS
3447 lseek (trace_fd, mlen, SEEK_CUR);
3448 pos += (8 + 2 + mlen);
3449 break;
3450 case 'V':
3451 lseek (trace_fd, 4 + 8, SEEK_CUR);
3452 pos += (4 + 8);
3453 break;
3454 default:
3455 error ("Unknown block type '%c' (0x%x) in trace frame",
3456 block_type, block_type);
3457 break;
3458 }
3459 }
3460}
3461
3462static LONGEST
3463tfile_xfer_partial (struct target_ops *ops, enum target_object object,
3464 const char *annex, gdb_byte *readbuf,
3465 const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
3466{
3467 char block_type;
98e03262 3468 int pos, gotten;
00bf0b85
SS
3469 ULONGEST maddr;
3470 unsigned short mlen;
3471
3472 /* We're only doing regular memory for now. */
3473 if (object != TARGET_OBJECT_MEMORY)
3474 return -1;
3475
3476 if (readbuf == NULL)
3477 error ("tfile_xfer_partial: trace file is read-only");
3478
3479 lseek (trace_fd, cur_offset, SEEK_SET);
3480 pos = 0;
3481 while (pos < cur_data_size)
3482 {
98e03262
SS
3483 gotten = read (trace_fd, &block_type, 1);
3484 if (gotten < 0)
3485 perror_with_name (trace_filename);
3486 else if (gotten < 1)
3487 error (_("Premature end of file while reading trace file"));
00bf0b85
SS
3488 ++pos;
3489 switch (block_type)
3490 {
3491 case 'R':
3492 lseek (trace_fd, trace_regblock_size, SEEK_CUR);
3493 pos += trace_regblock_size;
3494 break;
3495 case 'M':
98e03262
SS
3496 gotten = read (trace_fd, &maddr, 8);
3497 if (gotten < 0)
3498 perror_with_name (trace_filename);
3499 else if (gotten < 8)
3500 error (_("Premature end of file while reading trace file"));
3501
3502 gotten = read (trace_fd, &mlen, 2);
3503 if (gotten < 0)
3504 perror_with_name (trace_filename);
3505 else if (gotten < 2)
3506 error (_("Premature end of file while reading trace file"));
00bf0b85
SS
3507 if (maddr <= offset && (offset + len) <= (maddr + mlen))
3508 {
98e03262
SS
3509 gotten = read (trace_fd, readbuf, mlen);
3510 if (gotten < 0)
3511 perror_with_name (trace_filename);
3512 else if (gotten < mlen)
3513 error (_("Premature end of file qwhile reading trace file"));
3514
00bf0b85
SS
3515 return mlen;
3516 }
3517 lseek (trace_fd, mlen, SEEK_CUR);
3518 pos += (8 + 2 + mlen);
3519 break;
3520 case 'V':
3521 lseek (trace_fd, 4 + 8, SEEK_CUR);
3522 pos += (4 + 8);
3523 break;
3524 default:
3525 error ("Unknown block type '%c' (0x%x) in traceframe",
3526 block_type, block_type);
3527 break;
3528 }
3529 }
3530 /* Indicate failure to find the requested memory block. */
3531 return -1;
3532}
3533
3534/* Iterate through the blocks of a trace frame, looking for a 'V'
3535 block with a matching tsv number. */
3536
3537static int
3538tfile_get_trace_state_variable_value (int tsvnum, LONGEST *val)
3539{
3540 char block_type;
98e03262 3541 int pos, vnum, gotten;
00bf0b85
SS
3542 unsigned short mlen;
3543
3544 lseek (trace_fd, cur_offset, SEEK_SET);
3545 pos = 0;
3546 while (pos < cur_data_size)
3547 {
98e03262
SS
3548 gotten = read (trace_fd, &block_type, 1);
3549 if (gotten < 0)
3550 perror_with_name (trace_filename);
3551 else if (gotten < 1)
3552 error (_("Premature end of file while reading trace file"));
00bf0b85
SS
3553 ++pos;
3554 switch (block_type)
3555 {
3556 case 'R':
3557 lseek (trace_fd, trace_regblock_size, SEEK_CUR);
3558 pos += trace_regblock_size;
3559 break;
3560 case 'M':
3561 lseek (trace_fd, 8, SEEK_CUR);
98e03262
SS
3562 gotten = read (trace_fd, &mlen, 2);
3563 if (gotten < 0)
3564 perror_with_name (trace_filename);
3565 else if (gotten < 2)
3566 error (_("Premature end of file while reading trace file"));
00bf0b85
SS
3567 lseek (trace_fd, mlen, SEEK_CUR);
3568 pos += (8 + 2 + mlen);
3569 break;
3570 case 'V':
98e03262
SS
3571 gotten = read (trace_fd, &vnum, 4);
3572 if (gotten < 0)
3573 perror_with_name (trace_filename);
3574 else if (gotten < 4)
3575 error (_("Premature end of file while reading trace file"));
00bf0b85
SS
3576 if (tsvnum == vnum)
3577 {
98e03262
SS
3578 gotten = read (trace_fd, val, 8);
3579 if (gotten < 0)
3580 perror_with_name (trace_filename);
3581 else if (gotten < 8)
3582 error (_("Premature end of file while reading trace file"));
00bf0b85
SS
3583 return 1;
3584 }
3585 lseek (trace_fd, 8, SEEK_CUR);
3586 pos += (4 + 8);
3587 break;
3588 default:
3589 error ("Unknown block type '%c' (0x%x) in traceframe",
3590 block_type, block_type);
3591 break;
3592 }
3593 }
3594 /* Didn't find anything. */
3595 return 0;
3596}
3597
3598static int
3599tfile_has_memory (struct target_ops *ops)
3600{
3601 return 1;
3602}
3603
3604static int
3605tfile_has_stack (struct target_ops *ops)
3606{
3607 return 1;
3608}
3609
3610static int
3611tfile_has_registers (struct target_ops *ops)
3612{
3613 return 1;
3614}
3615
3616static void
3617init_tfile_ops (void)
3618{
3619 tfile_ops.to_shortname = "tfile";
3620 tfile_ops.to_longname = "Local trace dump file";
3621 tfile_ops.to_doc =
3622 "Use a trace file as a target. Specify the filename of the trace file.";
3623 tfile_ops.to_open = tfile_open;
3624 tfile_ops.to_close = tfile_close;
3625 tfile_ops.to_fetch_registers = tfile_fetch_registers;
3626 tfile_ops.to_xfer_partial = tfile_xfer_partial;
3627 tfile_ops.to_files_info = tfile_files_info;
3628 tfile_ops.to_get_trace_status = tfile_get_trace_status;
3629 tfile_ops.to_trace_find = tfile_trace_find;
3630 tfile_ops.to_get_trace_state_variable_value = tfile_get_trace_state_variable_value;
3631 /* core_stratum might seem more logical, but GDB doesn't like having
3632 more than one core_stratum vector. */
3633 tfile_ops.to_stratum = process_stratum;
3634 tfile_ops.to_has_memory = tfile_has_memory;
3635 tfile_ops.to_has_stack = tfile_has_stack;
3636 tfile_ops.to_has_registers = tfile_has_registers;
3637 tfile_ops.to_magic = OPS_MAGIC;
3638}
3639
c906108c
SS
3640/* module initialization */
3641void
fba45db2 3642_initialize_tracepoint (void)
c906108c 3643{
fa58ee11
EZ
3644 struct cmd_list_element *c;
3645
c906108c
SS
3646 traceframe_number = -1;
3647 tracepoint_number = -1;
3648
c906108c
SS
3649 if (tracepoint_list.list == NULL)
3650 {
3651 tracepoint_list.listsize = 128;
c5aa993b 3652 tracepoint_list.list = xmalloc
c906108c
SS
3653 (tracepoint_list.listsize * sizeof (struct memrange));
3654 }
3655 if (tracepoint_list.aexpr_list == NULL)
3656 {
3657 tracepoint_list.aexpr_listsize = 128;
3658 tracepoint_list.aexpr_list = xmalloc
3659 (tracepoint_list.aexpr_listsize * sizeof (struct agent_expr *));
3660 }
3661
3662 if (stepping_list.list == NULL)
3663 {
3664 stepping_list.listsize = 128;
c5aa993b 3665 stepping_list.list = xmalloc
c906108c
SS
3666 (stepping_list.listsize * sizeof (struct memrange));
3667 }
3668
3669 if (stepping_list.aexpr_list == NULL)
3670 {
3671 stepping_list.aexpr_listsize = 128;
3672 stepping_list.aexpr_list = xmalloc
3673 (stepping_list.aexpr_listsize * sizeof (struct agent_expr *));
3674 }
3675
c5aa993b 3676 add_info ("scope", scope_info,
1bedd215 3677 _("List the variables local to a scope"));
c906108c 3678
e00d1dc8 3679 add_cmd ("tracepoints", class_trace, NULL,
1a966eab 3680 _("Tracing of program execution without stopping the program."),
c906108c
SS
3681 &cmdlist);
3682
c5aa993b 3683 add_com ("tdump", class_trace, trace_dump_command,
1bedd215 3684 _("Print everything collected at the current tracepoint."));
c906108c 3685
00bf0b85
SS
3686 add_com ("tsave", class_trace, trace_save_command, _("\
3687Save the trace data to a file.\n\
3688Use the '-r' option to direct the target to save directly to the file,\n\
3689using its own filesystem."));
3690
f61e138d
SS
3691 c = add_com ("tvariable", class_trace, trace_variable_command,_("\
3692Define a trace state variable.\n\
3693Argument is a $-prefixed name, optionally followed\n\
3694by '=' and an expression that sets the initial value\n\
3695at the start of tracing."));
3696 set_cmd_completer (c, expression_completer);
3697
3698 add_cmd ("tvariable", class_trace, delete_trace_variable_command, _("\
3699Delete one or more trace state variables.\n\
3700Arguments are the names of the variables to delete.\n\
3701If no arguments are supplied, delete all variables."), &deletelist);
3702 /* FIXME add a trace variable completer */
3703
3704 add_info ("tvariables", tvariables_info, _("\
3705Status of trace state variables and their values.\n\
3706"));
3707
1bedd215
AC
3708 add_prefix_cmd ("tfind", class_trace, trace_find_command, _("\
3709Select a trace frame;\n\
3710No argument means forward by one frame; '-' means backward by one frame."),
c906108c
SS
3711 &tfindlist, "tfind ", 1, &cmdlist);
3712
1a966eab 3713 add_cmd ("outside", class_trace, trace_find_outside_command, _("\
081dfbf7 3714Select a trace frame whose PC is outside the given range (exclusive).\n\
1a966eab 3715Usage: tfind outside addr1, addr2"),
c906108c
SS
3716 &tfindlist);
3717
1a966eab 3718 add_cmd ("range", class_trace, trace_find_range_command, _("\
081dfbf7 3719Select a trace frame whose PC is in the given range (inclusive).\n\
1a966eab 3720Usage: tfind range addr1,addr2"),
c906108c
SS
3721 &tfindlist);
3722
1a966eab
AC
3723 add_cmd ("line", class_trace, trace_find_line_command, _("\
3724Select a trace frame by source line.\n\
c906108c
SS
3725Argument can be a line number (with optional source file), \n\
3726a function name, or '*' followed by an address.\n\
1a966eab 3727Default argument is 'the next source line that was traced'."),
c906108c
SS
3728 &tfindlist);
3729
1a966eab
AC
3730 add_cmd ("tracepoint", class_trace, trace_find_tracepoint_command, _("\
3731Select a trace frame by tracepoint number.\n\
3732Default is the tracepoint for the current trace frame."),
c906108c
SS
3733 &tfindlist);
3734
1a966eab
AC
3735 add_cmd ("pc", class_trace, trace_find_pc_command, _("\
3736Select a trace frame by PC.\n\
3737Default is the current PC, or the PC of the current trace frame."),
c906108c
SS
3738 &tfindlist);
3739
1a966eab
AC
3740 add_cmd ("end", class_trace, trace_find_end_command, _("\
3741Synonym for 'none'.\n\
3742De-select any trace frame and resume 'live' debugging."),
c906108c
SS
3743 &tfindlist);
3744
3745 add_cmd ("none", class_trace, trace_find_none_command,
1a966eab 3746 _("De-select any trace frame and resume 'live' debugging."),
c906108c
SS
3747 &tfindlist);
3748
3749 add_cmd ("start", class_trace, trace_find_start_command,
1a966eab 3750 _("Select the first trace frame in the trace buffer."),
c906108c
SS
3751 &tfindlist);
3752
c5aa993b 3753 add_com ("tstatus", class_trace, trace_status_command,
1bedd215 3754 _("Display the status of the current trace data collection."));
c906108c 3755
c5aa993b 3756 add_com ("tstop", class_trace, trace_stop_command,
1bedd215 3757 _("Stop trace data collection."));
c906108c
SS
3758
3759 add_com ("tstart", class_trace, trace_start_command,
1bedd215 3760 _("Start trace data collection."));
c906108c 3761
1bedd215
AC
3762 add_com ("end", class_trace, end_actions_pseudocommand, _("\
3763Ends a list of commands or actions.\n\
c906108c
SS
3764Several GDB commands allow you to enter a list of commands or actions.\n\
3765Entering \"end\" on a line by itself is the normal way to terminate\n\
3766such a list.\n\n\
1bedd215 3767Note: the \"end\" command cannot be used at the gdb prompt."));
c906108c 3768
1bedd215
AC
3769 add_com ("while-stepping", class_trace, while_stepping_pseudocommand, _("\
3770Specify single-stepping behavior at a tracepoint.\n\
c906108c
SS
3771Argument is number of instructions to trace in single-step mode\n\
3772following the tracepoint. This command is normally followed by\n\
3773one or more \"collect\" commands, to specify what to collect\n\
3774while single-stepping.\n\n\
1bedd215 3775Note: this command can only be used in a tracepoint \"actions\" list."));
c906108c 3776
c5aa993b
JM
3777 add_com_alias ("ws", "while-stepping", class_alias, 0);
3778 add_com_alias ("stepping", "while-stepping", class_alias, 0);
c906108c 3779
1bedd215
AC
3780 add_com ("collect", class_trace, collect_pseudocommand, _("\
3781Specify one or more data items to be collected at a tracepoint.\n\
c906108c
SS
3782Accepts a comma-separated list of (one or more) expressions. GDB will\n\
3783collect all data (variables, registers) referenced by that expression.\n\
3784Also accepts the following special arguments:\n\
3785 $regs -- all registers.\n\
3786 $args -- all function arguments.\n\
3787 $locals -- all variables local to the block/function scope.\n\
1bedd215 3788Note: this command can only be used in a tracepoint \"actions\" list."));
c906108c 3789
6da95a67
SS
3790 add_com ("teval", class_trace, teval_pseudocommand, _("\
3791Specify one or more expressions to be evaluated at a tracepoint.\n\
3792Accepts a comma-separated list of (one or more) expressions.\n\
3793The result of each evaluation will be discarded.\n\
3794Note: this command can only be used in a tracepoint \"actions\" list."));
3795
1bedd215
AC
3796 add_com ("actions", class_trace, trace_actions_command, _("\
3797Specify the actions to be taken at a tracepoint.\n\
c906108c
SS
3798Tracepoint actions may include collecting of specified data, \n\
3799single-stepping, or enabling/disabling other tracepoints, \n\
1bedd215 3800depending on target's capabilities."));
c906108c 3801
236f1d4d
SS
3802 default_collect = xstrdup ("");
3803 add_setshow_string_cmd ("default-collect", class_trace,
3804 &default_collect, _("\
3805Set the list of expressions to collect by default"), _("\
3806Show the list of expressions to collect by default"), NULL,
3807 NULL, NULL,
3808 &setlist, &showlist);
3809
d5551862
SS
3810 add_setshow_boolean_cmd ("disconnected-tracing", no_class,
3811 &disconnected_tracing, _("\
3812Set whether tracing continues after GDB disconnects."), _("\
3813Show whether tracing continues after GDB disconnects."), _("\
3814Use this to continue a tracing run even if GDB disconnects\n\
3815or detaches from the target. You can reconnect later and look at\n\
3816trace data collected in the meantime."),
3817 set_disconnected_tracing,
3818 NULL,
3819 &setlist,
3820 &showlist);
00bf0b85
SS
3821
3822 init_tfile_ops ();
3823
3824 add_target (&tfile_ops);
c906108c 3825}
This page took 1.218978 seconds and 4 git commands to generate.