GDB (API)
/home/stan/gdb/src/gdb/tracepoint.c
Go to the documentation of this file.
00001 /* Tracing functionality for remote targets in custom GDB protocol
00002 
00003    Copyright (C) 1997-2013 Free Software Foundation, Inc.
00004 
00005    This file is part of GDB.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 3 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00019 
00020 #include "defs.h"
00021 #include "arch-utils.h"
00022 #include "symtab.h"
00023 #include "frame.h"
00024 #include "gdbtypes.h"
00025 #include "expression.h"
00026 #include "gdbcmd.h"
00027 #include "value.h"
00028 #include "target.h"
00029 #include "language.h"
00030 #include "gdb_string.h"
00031 #include "inferior.h"
00032 #include "breakpoint.h"
00033 #include "tracepoint.h"
00034 #include "linespec.h"
00035 #include "regcache.h"
00036 #include "completer.h"
00037 #include "block.h"
00038 #include "dictionary.h"
00039 #include "observer.h"
00040 #include "user-regs.h"
00041 #include "valprint.h"
00042 #include "gdbcore.h"
00043 #include "objfiles.h"
00044 #include "filenames.h"
00045 #include "gdbthread.h"
00046 #include "stack.h"
00047 #include "gdbcore.h"
00048 #include "remote.h"
00049 #include "source.h"
00050 #include "ax.h"
00051 #include "ax-gdb.h"
00052 #include "memrange.h"
00053 #include "exceptions.h"
00054 #include "cli/cli-utils.h"
00055 #include "probe.h"
00056 #include "ctf.h"
00057 #include "completer.h"
00058 #include "filestuff.h"
00059 
00060 /* readline include files */
00061 #include "readline/readline.h"
00062 #include "readline/history.h"
00063 
00064 /* readline defines this.  */
00065 #undef savestring
00066 
00067 #include <unistd.h>
00068 
00069 #ifndef O_LARGEFILE
00070 #define O_LARGEFILE 0
00071 #endif
00072 
00073 /* Maximum length of an agent aexpression.
00074    This accounts for the fact that packets are limited to 400 bytes
00075    (which includes everything -- including the checksum), and assumes
00076    the worst case of maximum length for each of the pieces of a
00077    continuation packet.
00078 
00079    NOTE: expressions get mem2hex'ed otherwise this would be twice as
00080    large.  (400 - 31)/2 == 184 */
00081 #define MAX_AGENT_EXPR_LEN      184
00082 
00083 /* A hook used to notify the UI of tracepoint operations.  */
00084 
00085 void (*deprecated_trace_find_hook) (char *arg, int from_tty);
00086 void (*deprecated_trace_start_stop_hook) (int start, int from_tty);
00087 
00088 /* 
00089    Tracepoint.c:
00090 
00091    This module defines the following debugger commands:
00092    trace            : set a tracepoint on a function, line, or address.
00093    info trace       : list all debugger-defined tracepoints.
00094    delete trace     : delete one or more tracepoints.
00095    enable trace     : enable one or more tracepoints.
00096    disable trace    : disable one or more tracepoints.
00097    actions          : specify actions to be taken at a tracepoint.
00098    passcount        : specify a pass count for a tracepoint.
00099    tstart           : start a trace experiment.
00100    tstop            : stop a trace experiment.
00101    tstatus          : query the status of a trace experiment.
00102    tfind            : find a trace frame in the trace buffer.
00103    tdump            : print everything collected at the current tracepoint.
00104    save-tracepoints : write tracepoint setup into a file.
00105 
00106    This module defines the following user-visible debugger variables:
00107    $trace_frame : sequence number of trace frame currently being debugged.
00108    $trace_line  : source line of trace frame currently being debugged.
00109    $trace_file  : source file of trace frame currently being debugged.
00110    $tracepoint  : tracepoint number of trace frame currently being debugged.
00111  */
00112 
00113 
00114 /* ======= Important global variables: ======= */
00115 
00116 /* The list of all trace state variables.  We don't retain pointers to
00117    any of these for any reason - API is by name or number only - so it
00118    works to have a vector of objects.  */
00119 
00120 typedef struct trace_state_variable tsv_s;
00121 DEF_VEC_O(tsv_s);
00122 
00123 static VEC(tsv_s) *tvariables;
00124 
00125 /* The next integer to assign to a variable.  */
00126 
00127 static int next_tsv_number = 1;
00128 
00129 /* Number of last traceframe collected.  */
00130 static int traceframe_number;
00131 
00132 /* Tracepoint for last traceframe collected.  */
00133 static int tracepoint_number;
00134 
00135 /* Symbol for function for last traceframe collected.  */
00136 static struct symbol *traceframe_fun;
00137 
00138 /* Symtab and line for last traceframe collected.  */
00139 static struct symtab_and_line traceframe_sal;
00140 
00141 /* The traceframe info of the current traceframe.  NULL if we haven't
00142    yet attempted to fetch it, or if the target does not support
00143    fetching this object, or if we're not inspecting a traceframe
00144    presently.  */
00145 static struct traceframe_info *traceframe_info;
00146 
00147 /* Tracing command lists.  */
00148 static struct cmd_list_element *tfindlist;
00149 
00150 /* List of expressions to collect by default at each tracepoint hit.  */
00151 char *default_collect = "";
00152 
00153 static int disconnected_tracing;
00154 
00155 /* This variable controls whether we ask the target for a linear or
00156    circular trace buffer.  */
00157 
00158 static int circular_trace_buffer;
00159 
00160 /* This variable is the requested trace buffer size, or -1 to indicate
00161    that we don't care and leave it up to the target to set a size.  */
00162 
00163 static int trace_buffer_size = -1;
00164 
00165 /* Textual notes applying to the current and/or future trace runs.  */
00166 
00167 char *trace_user = NULL;
00168 
00169 /* Textual notes applying to the current and/or future trace runs.  */
00170 
00171 char *trace_notes = NULL;
00172 
00173 /* Textual notes applying to the stopping of a trace.  */
00174 
00175 char *trace_stop_notes = NULL;
00176 
00177 /* ======= Important command functions: ======= */
00178 static void trace_actions_command (char *, int);
00179 static void trace_start_command (char *, int);
00180 static void trace_stop_command (char *, int);
00181 static void trace_status_command (char *, int);
00182 static void trace_find_command (char *, int);
00183 static void trace_find_pc_command (char *, int);
00184 static void trace_find_tracepoint_command (char *, int);
00185 static void trace_find_line_command (char *, int);
00186 static void trace_find_range_command (char *, int);
00187 static void trace_find_outside_command (char *, int);
00188 static void trace_dump_command (char *, int);
00189 
00190 /* support routines */
00191 
00192 struct collection_list;
00193 static void add_aexpr (struct collection_list *, struct agent_expr *);
00194 static char *mem2hex (gdb_byte *, char *, int);
00195 static void add_register (struct collection_list *collection,
00196                           unsigned int regno);
00197 
00198 static void free_uploaded_tps (struct uploaded_tp **utpp);
00199 static void free_uploaded_tsvs (struct uploaded_tsv **utsvp);
00200 
00201 static struct command_line *
00202   all_tracepoint_actions_and_cleanup (struct breakpoint *t);
00203 
00204 extern void _initialize_tracepoint (void);
00205 
00206 static struct trace_status trace_status;
00207 
00208 char *stop_reason_names[] = {
00209   "tunknown",
00210   "tnotrun",
00211   "tstop",
00212   "tfull",
00213   "tdisconnected",
00214   "tpasscount",
00215   "terror"
00216 };
00217 
00218 struct trace_status *
00219 current_trace_status (void)
00220 {
00221   return &trace_status;
00222 }
00223 
00224 /* Destroy INFO.  */
00225 
00226 static void
00227 free_traceframe_info (struct traceframe_info *info)
00228 {
00229   if (info != NULL)
00230     {
00231       VEC_free (mem_range_s, info->memory);
00232       VEC_free (int, info->tvars);
00233 
00234       xfree (info);
00235     }
00236 }
00237 
00238 /* Free and clear the traceframe info cache of the current
00239    traceframe.  */
00240 
00241 static void
00242 clear_traceframe_info (void)
00243 {
00244   free_traceframe_info (traceframe_info);
00245   traceframe_info = NULL;
00246 }
00247 
00248 /* Set traceframe number to NUM.  */
00249 static void
00250 set_traceframe_num (int num)
00251 {
00252   traceframe_number = num;
00253   set_internalvar_integer (lookup_internalvar ("trace_frame"), num);
00254 }
00255 
00256 /* Set tracepoint number to NUM.  */
00257 static void
00258 set_tracepoint_num (int num)
00259 {
00260   tracepoint_number = num;
00261   set_internalvar_integer (lookup_internalvar ("tracepoint"), num);
00262 }
00263 
00264 /* Set externally visible debug variables for querying/printing
00265    the traceframe context (line, function, file).  */
00266 
00267 static void
00268 set_traceframe_context (struct frame_info *trace_frame)
00269 {
00270   CORE_ADDR trace_pc;
00271 
00272   /* Save as globals for internal use.  */
00273   if (trace_frame != NULL
00274       && get_frame_pc_if_available (trace_frame, &trace_pc))
00275     {
00276       traceframe_sal = find_pc_line (trace_pc, 0);
00277       traceframe_fun = find_pc_function (trace_pc);
00278 
00279       /* Save linenumber as "$trace_line", a debugger variable visible to
00280          users.  */
00281       set_internalvar_integer (lookup_internalvar ("trace_line"),
00282                                traceframe_sal.line);
00283     }
00284   else
00285     {
00286       init_sal (&traceframe_sal);
00287       traceframe_fun = NULL;
00288       set_internalvar_integer (lookup_internalvar ("trace_line"), -1);
00289     }
00290 
00291   /* Save func name as "$trace_func", a debugger variable visible to
00292      users.  */
00293   if (traceframe_fun == NULL
00294       || SYMBOL_LINKAGE_NAME (traceframe_fun) == NULL)
00295     clear_internalvar (lookup_internalvar ("trace_func"));
00296   else
00297     set_internalvar_string (lookup_internalvar ("trace_func"),
00298                             SYMBOL_LINKAGE_NAME (traceframe_fun));
00299 
00300   /* Save file name as "$trace_file", a debugger variable visible to
00301      users.  */
00302   if (traceframe_sal.symtab == NULL)
00303     clear_internalvar (lookup_internalvar ("trace_file"));
00304   else
00305     set_internalvar_string (lookup_internalvar ("trace_file"),
00306                         symtab_to_filename_for_display (traceframe_sal.symtab));
00307 }
00308 
00309 /* Create a new trace state variable with the given name.  */
00310 
00311 struct trace_state_variable *
00312 create_trace_state_variable (const char *name)
00313 {
00314   struct trace_state_variable tsv;
00315 
00316   memset (&tsv, 0, sizeof (tsv));
00317   tsv.name = xstrdup (name);
00318   tsv.number = next_tsv_number++;
00319   return VEC_safe_push (tsv_s, tvariables, &tsv);
00320 }
00321 
00322 /* Look for a trace state variable of the given name.  */
00323 
00324 struct trace_state_variable *
00325 find_trace_state_variable (const char *name)
00326 {
00327   struct trace_state_variable *tsv;
00328   int ix;
00329 
00330   for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
00331     if (strcmp (name, tsv->name) == 0)
00332       return tsv;
00333 
00334   return NULL;
00335 }
00336 
00337 /* Look for a trace state variable of the given number.  Return NULL if
00338    not found.  */
00339 
00340 struct trace_state_variable *
00341 find_trace_state_variable_by_number (int number)
00342 {
00343   struct trace_state_variable *tsv;
00344   int ix;
00345 
00346   for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
00347     if (tsv->number == number)
00348       return tsv;
00349 
00350   return NULL;
00351 }
00352 
00353 static void
00354 delete_trace_state_variable (const char *name)
00355 {
00356   struct trace_state_variable *tsv;
00357   int ix;
00358 
00359   for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
00360     if (strcmp (name, tsv->name) == 0)
00361       {
00362         observer_notify_tsv_deleted (tsv);
00363 
00364         xfree ((void *)tsv->name);
00365         VEC_unordered_remove (tsv_s, tvariables, ix);
00366 
00367         return;
00368       }
00369 
00370   warning (_("No trace variable named \"$%s\", not deleting"), name);
00371 }
00372 
00373 /* Throws an error if NAME is not valid syntax for a trace state
00374    variable's name.  */
00375 
00376 void
00377 validate_trace_state_variable_name (const char *name)
00378 {
00379   const char *p;
00380 
00381   if (*name == '\0')
00382     error (_("Must supply a non-empty variable name"));
00383 
00384   /* All digits in the name is reserved for value history
00385      references.  */
00386   for (p = name; isdigit (*p); p++)
00387     ;
00388   if (*p == '\0')
00389     error (_("$%s is not a valid trace state variable name"), name);
00390 
00391   for (p = name; isalnum (*p) || *p == '_'; p++)
00392     ;
00393   if (*p != '\0')
00394     error (_("$%s is not a valid trace state variable name"), name);
00395 }
00396 
00397 /* The 'tvariable' command collects a name and optional expression to
00398    evaluate into an initial value.  */
00399 
00400 static void
00401 trace_variable_command (char *args, int from_tty)
00402 {
00403   struct cleanup *old_chain;
00404   LONGEST initval = 0;
00405   struct trace_state_variable *tsv;
00406   char *name, *p;
00407 
00408   if (!args || !*args)
00409     error_no_arg (_("Syntax is $NAME [ = EXPR ]"));
00410 
00411   /* Only allow two syntaxes; "$name" and "$name=value".  */
00412   p = skip_spaces (args);
00413 
00414   if (*p++ != '$')
00415     error (_("Name of trace variable should start with '$'"));
00416 
00417   name = p;
00418   while (isalnum (*p) || *p == '_')
00419     p++;
00420   name = savestring (name, p - name);
00421   old_chain = make_cleanup (xfree, name);
00422 
00423   p = skip_spaces (p);
00424   if (*p != '=' && *p != '\0')
00425     error (_("Syntax must be $NAME [ = EXPR ]"));
00426 
00427   validate_trace_state_variable_name (name);
00428 
00429   if (*p == '=')
00430     initval = value_as_long (parse_and_eval (++p));
00431 
00432   /* If the variable already exists, just change its initial value.  */
00433   tsv = find_trace_state_variable (name);
00434   if (tsv)
00435     {
00436       if (tsv->initial_value != initval)
00437         {
00438           tsv->initial_value = initval;
00439           observer_notify_tsv_modified (tsv);
00440         }
00441       printf_filtered (_("Trace state variable $%s "
00442                          "now has initial value %s.\n"),
00443                        tsv->name, plongest (tsv->initial_value));
00444       do_cleanups (old_chain);
00445       return;
00446     }
00447 
00448   /* Create a new variable.  */
00449   tsv = create_trace_state_variable (name);
00450   tsv->initial_value = initval;
00451 
00452   observer_notify_tsv_created (tsv);
00453 
00454   printf_filtered (_("Trace state variable $%s "
00455                      "created, with initial value %s.\n"),
00456                    tsv->name, plongest (tsv->initial_value));
00457 
00458   do_cleanups (old_chain);
00459 }
00460 
00461 static void
00462 delete_trace_variable_command (char *args, int from_tty)
00463 {
00464   int ix;
00465   char **argv;
00466   struct cleanup *back_to;
00467 
00468   if (args == NULL)
00469     {
00470       if (query (_("Delete all trace state variables? ")))
00471         VEC_free (tsv_s, tvariables);
00472       dont_repeat ();
00473       observer_notify_tsv_deleted (NULL);
00474       return;
00475     }
00476 
00477   argv = gdb_buildargv (args);
00478   back_to = make_cleanup_freeargv (argv);
00479 
00480   for (ix = 0; argv[ix] != NULL; ix++)
00481     {
00482       if (*argv[ix] == '$')
00483         delete_trace_state_variable (argv[ix] + 1);
00484       else
00485         warning (_("Name \"%s\" not prefixed with '$', ignoring"), argv[ix]);
00486     }
00487 
00488   do_cleanups (back_to);
00489 
00490   dont_repeat ();
00491 }
00492 
00493 void
00494 tvariables_info_1 (void)
00495 {
00496   struct trace_state_variable *tsv;
00497   int ix;
00498   int count = 0;
00499   struct cleanup *back_to;
00500   struct ui_out *uiout = current_uiout;
00501 
00502   if (VEC_length (tsv_s, tvariables) == 0 && !ui_out_is_mi_like_p (uiout))
00503     {
00504       printf_filtered (_("No trace state variables.\n"));
00505       return;
00506     }
00507 
00508   /* Try to acquire values from the target.  */
00509   for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix, ++count)
00510     tsv->value_known = target_get_trace_state_variable_value (tsv->number,
00511                                                               &(tsv->value));
00512 
00513   back_to = make_cleanup_ui_out_table_begin_end (uiout, 3,
00514                                                  count, "trace-variables");
00515   ui_out_table_header (uiout, 15, ui_left, "name", "Name");
00516   ui_out_table_header (uiout, 11, ui_left, "initial", "Initial");
00517   ui_out_table_header (uiout, 11, ui_left, "current", "Current");
00518 
00519   ui_out_table_body (uiout);
00520 
00521   for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
00522     {
00523       struct cleanup *back_to2;
00524       char *c;
00525       char *name;
00526 
00527       back_to2 = make_cleanup_ui_out_tuple_begin_end (uiout, "variable");
00528 
00529       name = concat ("$", tsv->name, (char *) NULL);
00530       make_cleanup (xfree, name);
00531       ui_out_field_string (uiout, "name", name);
00532       ui_out_field_string (uiout, "initial", plongest (tsv->initial_value));
00533 
00534       if (tsv->value_known)
00535         c = plongest (tsv->value);
00536       else if (ui_out_is_mi_like_p (uiout))
00537         /* For MI, we prefer not to use magic string constants, but rather
00538            omit the field completely.  The difference between unknown and
00539            undefined does not seem important enough to represent.  */
00540         c = NULL;
00541       else if (current_trace_status ()->running || traceframe_number >= 0)
00542         /* The value is/was defined, but we don't have it.  */
00543         c = "<unknown>";
00544       else
00545         /* It is not meaningful to ask about the value.  */
00546         c = "<undefined>";
00547       if (c)
00548         ui_out_field_string (uiout, "current", c);
00549       ui_out_text (uiout, "\n");
00550 
00551       do_cleanups (back_to2);
00552     }
00553 
00554   do_cleanups (back_to);
00555 }
00556 
00557 /* List all the trace state variables.  */
00558 
00559 static void
00560 tvariables_info (char *args, int from_tty)
00561 {
00562   tvariables_info_1 ();
00563 }
00564 
00565 /* Stash definitions of tsvs into the given file.  */
00566 
00567 void
00568 save_trace_state_variables (struct ui_file *fp)
00569 {
00570   struct trace_state_variable *tsv;
00571   int ix;
00572 
00573   for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
00574     {
00575       fprintf_unfiltered (fp, "tvariable $%s", tsv->name);
00576       if (tsv->initial_value)
00577         fprintf_unfiltered (fp, " = %s", plongest (tsv->initial_value));
00578       fprintf_unfiltered (fp, "\n");
00579     }
00580 }
00581 
00582 /* ACTIONS functions: */
00583 
00584 /* The three functions:
00585    collect_pseudocommand, 
00586    while_stepping_pseudocommand, and 
00587    end_actions_pseudocommand
00588    are placeholders for "commands" that are actually ONLY to be used
00589    within a tracepoint action list.  If the actual function is ever called,
00590    it means that somebody issued the "command" at the top level,
00591    which is always an error.  */
00592 
00593 static void
00594 end_actions_pseudocommand (char *args, int from_tty)
00595 {
00596   error (_("This command cannot be used at the top level."));
00597 }
00598 
00599 static void
00600 while_stepping_pseudocommand (char *args, int from_tty)
00601 {
00602   error (_("This command can only be used in a tracepoint actions list."));
00603 }
00604 
00605 static void
00606 collect_pseudocommand (char *args, int from_tty)
00607 {
00608   error (_("This command can only be used in a tracepoint actions list."));
00609 }
00610 
00611 static void
00612 teval_pseudocommand (char *args, int from_tty)
00613 {
00614   error (_("This command can only be used in a tracepoint actions list."));
00615 }
00616 
00617 /* Parse any collection options, such as /s for strings.  */
00618 
00619 const char *
00620 decode_agent_options (const char *exp, int *trace_string)
00621 {
00622   struct value_print_options opts;
00623 
00624   *trace_string = 0;
00625 
00626   if (*exp != '/')
00627     return exp;
00628 
00629   /* Call this to borrow the print elements default for collection
00630      size.  */
00631   get_user_print_options (&opts);
00632 
00633   exp++;
00634   if (*exp == 's')
00635     {
00636       if (target_supports_string_tracing ())
00637         {
00638           /* Allow an optional decimal number giving an explicit maximum
00639              string length, defaulting it to the "print elements" value;
00640              so "collect/s80 mystr" gets at most 80 bytes of string.  */
00641           *trace_string = opts.print_max;
00642           exp++;
00643           if (*exp >= '0' && *exp <= '9')
00644             *trace_string = atoi (exp);
00645           while (*exp >= '0' && *exp <= '9')
00646             exp++;
00647         }
00648       else
00649         error (_("Target does not support \"/s\" option for string tracing."));
00650     }
00651   else
00652     error (_("Undefined collection format \"%c\"."), *exp);
00653 
00654   exp = skip_spaces_const (exp);
00655 
00656   return exp;
00657 }
00658 
00659 /* Enter a list of actions for a tracepoint.  */
00660 static void
00661 trace_actions_command (char *args, int from_tty)
00662 {
00663   struct tracepoint *t;
00664   struct command_line *l;
00665 
00666   t = get_tracepoint_by_number (&args, NULL, 1);
00667   if (t)
00668     {
00669       char *tmpbuf =
00670         xstrprintf ("Enter actions for tracepoint %d, one per line.",
00671                     t->base.number);
00672       struct cleanup *cleanups = make_cleanup (xfree, tmpbuf);
00673 
00674       l = read_command_lines (tmpbuf, from_tty, 1,
00675                               check_tracepoint_command, t);
00676       do_cleanups (cleanups);
00677       breakpoint_set_commands (&t->base, l);
00678     }
00679   /* else just return */
00680 }
00681 
00682 /* Report the results of checking the agent expression, as errors or
00683    internal errors.  */
00684 
00685 static void
00686 report_agent_reqs_errors (struct agent_expr *aexpr)
00687 {
00688   /* All of the "flaws" are serious bytecode generation issues that
00689      should never occur.  */
00690   if (aexpr->flaw != agent_flaw_none)
00691     internal_error (__FILE__, __LINE__, _("expression is malformed"));
00692 
00693   /* If analysis shows a stack underflow, GDB must have done something
00694      badly wrong in its bytecode generation.  */
00695   if (aexpr->min_height < 0)
00696     internal_error (__FILE__, __LINE__,
00697                     _("expression has min height < 0"));
00698 
00699   /* Issue this error if the stack is predicted to get too deep.  The
00700      limit is rather arbitrary; a better scheme might be for the
00701      target to report how much stack it will have available.  The
00702      depth roughly corresponds to parenthesization, so a limit of 20
00703      amounts to 20 levels of expression nesting, which is actually
00704      a pretty big hairy expression.  */
00705   if (aexpr->max_height > 20)
00706     error (_("Expression is too complicated."));
00707 }
00708 
00709 /* worker function */
00710 void
00711 validate_actionline (const char *line, struct breakpoint *b)
00712 {
00713   struct cmd_list_element *c;
00714   struct expression *exp = NULL;
00715   struct cleanup *old_chain = NULL;
00716   const char *tmp_p;
00717   const char *p;
00718   struct bp_location *loc;
00719   struct agent_expr *aexpr;
00720   struct tracepoint *t = (struct tracepoint *) b;
00721 
00722   /* If EOF is typed, *line is NULL.  */
00723   if (line == NULL)
00724     return;
00725 
00726   p = skip_spaces_const (line);
00727 
00728   /* Symbol lookup etc.  */
00729   if (*p == '\0')       /* empty line: just prompt for another line.  */
00730     return;
00731 
00732   if (*p == '#')                /* comment line */
00733     return;
00734 
00735   c = lookup_cmd (&p, cmdlist, "", -1, 1);
00736   if (c == 0)
00737     error (_("`%s' is not a tracepoint action, or is ambiguous."), p);
00738 
00739   if (cmd_cfunc_eq (c, collect_pseudocommand))
00740     {
00741       int trace_string = 0;
00742 
00743       if (*p == '/')
00744         p = decode_agent_options (p, &trace_string);
00745 
00746       do
00747         {                       /* Repeat over a comma-separated list.  */
00748           QUIT;                 /* Allow user to bail out with ^C.  */
00749           p = skip_spaces_const (p);
00750 
00751           if (*p == '$')        /* Look for special pseudo-symbols.  */
00752             {
00753               if (0 == strncasecmp ("reg", p + 1, 3)
00754                   || 0 == strncasecmp ("arg", p + 1, 3)
00755                   || 0 == strncasecmp ("loc", p + 1, 3)
00756                   || 0 == strncasecmp ("_ret", p + 1, 4)
00757                   || 0 == strncasecmp ("_sdata", p + 1, 6))
00758                 {
00759                   p = strchr (p, ',');
00760                   continue;
00761                 }
00762               /* else fall thru, treat p as an expression and parse it!  */
00763             }
00764           tmp_p = p;
00765           for (loc = t->base.loc; loc; loc = loc->next)
00766             {
00767               p = tmp_p;
00768               exp = parse_exp_1 (&p, loc->address,
00769                                  block_for_pc (loc->address), 1);
00770               old_chain = make_cleanup (free_current_contents, &exp);
00771 
00772               if (exp->elts[0].opcode == OP_VAR_VALUE)
00773                 {
00774                   if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_CONST)
00775                     {
00776                       error (_("constant `%s' (value %s) "
00777                                "will not be collected."),
00778                              SYMBOL_PRINT_NAME (exp->elts[2].symbol),
00779                              plongest (SYMBOL_VALUE (exp->elts[2].symbol)));
00780                     }
00781                   else if (SYMBOL_CLASS (exp->elts[2].symbol)
00782                            == LOC_OPTIMIZED_OUT)
00783                     {
00784                       error (_("`%s' is optimized away "
00785                                "and cannot be collected."),
00786                              SYMBOL_PRINT_NAME (exp->elts[2].symbol));
00787                     }
00788                 }
00789 
00790               /* We have something to collect, make sure that the expr to
00791                  bytecode translator can handle it and that it's not too
00792                  long.  */
00793               aexpr = gen_trace_for_expr (loc->address, exp, trace_string);
00794               make_cleanup_free_agent_expr (aexpr);
00795 
00796               if (aexpr->len > MAX_AGENT_EXPR_LEN)
00797                 error (_("Expression is too complicated."));
00798 
00799               ax_reqs (aexpr);
00800 
00801               report_agent_reqs_errors (aexpr);
00802 
00803               do_cleanups (old_chain);
00804             }
00805         }
00806       while (p && *p++ == ',');
00807     }
00808 
00809   else if (cmd_cfunc_eq (c, teval_pseudocommand))
00810     {
00811       do
00812         {                       /* Repeat over a comma-separated list.  */
00813           QUIT;                 /* Allow user to bail out with ^C.  */
00814           p = skip_spaces_const (p);
00815 
00816           tmp_p = p;
00817           for (loc = t->base.loc; loc; loc = loc->next)
00818             {
00819               p = tmp_p;
00820 
00821               /* Only expressions are allowed for this action.  */
00822               exp = parse_exp_1 (&p, loc->address,
00823                                  block_for_pc (loc->address), 1);
00824               old_chain = make_cleanup (free_current_contents, &exp);
00825 
00826               /* We have something to evaluate, make sure that the expr to
00827                  bytecode translator can handle it and that it's not too
00828                  long.  */
00829               aexpr = gen_eval_for_expr (loc->address, exp);
00830               make_cleanup_free_agent_expr (aexpr);
00831 
00832               if (aexpr->len > MAX_AGENT_EXPR_LEN)
00833                 error (_("Expression is too complicated."));
00834 
00835               ax_reqs (aexpr);
00836               report_agent_reqs_errors (aexpr);
00837 
00838               do_cleanups (old_chain);
00839             }
00840         }
00841       while (p && *p++ == ',');
00842     }
00843 
00844   else if (cmd_cfunc_eq (c, while_stepping_pseudocommand))
00845     {
00846       char *endp;
00847 
00848       p = skip_spaces_const (p);
00849       t->step_count = strtol (p, &endp, 0);
00850       if (endp == p || t->step_count == 0)
00851         error (_("while-stepping step count `%s' is malformed."), line);
00852       p = endp;
00853     }
00854 
00855   else if (cmd_cfunc_eq (c, end_actions_pseudocommand))
00856     ;
00857 
00858   else
00859     error (_("`%s' is not a supported tracepoint action."), line);
00860 }
00861 
00862 enum {
00863   memrange_absolute = -1
00864 };
00865 
00866 /* MEMRANGE functions: */
00867 
00868 static int memrange_cmp (const void *, const void *);
00869 
00870 /* Compare memranges for qsort.  */
00871 static int
00872 memrange_cmp (const void *va, const void *vb)
00873 {
00874   const struct memrange *a = va, *b = vb;
00875 
00876   if (a->type < b->type)
00877     return -1;
00878   if (a->type > b->type)
00879     return 1;
00880   if (a->type == memrange_absolute)
00881     {
00882       if ((bfd_vma) a->start < (bfd_vma) b->start)
00883         return -1;
00884       if ((bfd_vma) a->start > (bfd_vma) b->start)
00885         return 1;
00886     }
00887   else
00888     {
00889       if (a->start < b->start)
00890         return -1;
00891       if (a->start > b->start)
00892         return 1;
00893     }
00894   return 0;
00895 }
00896 
00897 /* Sort the memrange list using qsort, and merge adjacent memranges.  */
00898 static void
00899 memrange_sortmerge (struct collection_list *memranges)
00900 {
00901   int a, b;
00902 
00903   qsort (memranges->list, memranges->next_memrange,
00904          sizeof (struct memrange), memrange_cmp);
00905   if (memranges->next_memrange > 0)
00906     {
00907       for (a = 0, b = 1; b < memranges->next_memrange; b++)
00908         {
00909           /* If memrange b overlaps or is adjacent to memrange a,
00910              merge them.  */
00911           if (memranges->list[a].type == memranges->list[b].type
00912               && memranges->list[b].start <= memranges->list[a].end)
00913             {
00914               if (memranges->list[b].end > memranges->list[a].end)
00915                 memranges->list[a].end = memranges->list[b].end;
00916               continue;         /* next b, same a */
00917             }
00918           a++;                  /* next a */
00919           if (a != b)
00920             memcpy (&memranges->list[a], &memranges->list[b],
00921                     sizeof (struct memrange));
00922         }
00923       memranges->next_memrange = a + 1;
00924     }
00925 }
00926 
00927 /* Add a register to a collection list.  */
00928 static void
00929 add_register (struct collection_list *collection, unsigned int regno)
00930 {
00931   if (info_verbose)
00932     printf_filtered ("collect register %d\n", regno);
00933   if (regno >= (8 * sizeof (collection->regs_mask)))
00934     error (_("Internal: register number %d too large for tracepoint"),
00935            regno);
00936   collection->regs_mask[regno / 8] |= 1 << (regno % 8);
00937 }
00938 
00939 /* Add a memrange to a collection list.  */
00940 static void
00941 add_memrange (struct collection_list *memranges, 
00942               int type, bfd_signed_vma base,
00943               unsigned long len)
00944 {
00945   if (info_verbose)
00946     {
00947       printf_filtered ("(%d,", type);
00948       printf_vma (base);
00949       printf_filtered (",%ld)\n", len);
00950     }
00951 
00952   /* type: memrange_absolute == memory, other n == basereg */
00953   memranges->list[memranges->next_memrange].type = type;
00954   /* base: addr if memory, offset if reg relative.  */
00955   memranges->list[memranges->next_memrange].start = base;
00956   /* len: we actually save end (base + len) for convenience */
00957   memranges->list[memranges->next_memrange].end = base + len;
00958   memranges->next_memrange++;
00959   if (memranges->next_memrange >= memranges->listsize)
00960     {
00961       memranges->listsize *= 2;
00962       memranges->list = xrealloc (memranges->list,
00963                                   memranges->listsize);
00964     }
00965 
00966   if (type != memrange_absolute)    /* Better collect the base register!  */
00967     add_register (memranges, type);
00968 }
00969 
00970 /* Add a symbol to a collection list.  */
00971 static void
00972 collect_symbol (struct collection_list *collect, 
00973                 struct symbol *sym,
00974                 struct gdbarch *gdbarch,
00975                 long frame_regno, long frame_offset,
00976                 CORE_ADDR scope,
00977                 int trace_string)
00978 {
00979   unsigned long len;
00980   unsigned int reg;
00981   bfd_signed_vma offset;
00982   int treat_as_expr = 0;
00983 
00984   len = TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym)));
00985   switch (SYMBOL_CLASS (sym))
00986     {
00987     default:
00988       printf_filtered ("%s: don't know symbol class %d\n",
00989                        SYMBOL_PRINT_NAME (sym),
00990                        SYMBOL_CLASS (sym));
00991       break;
00992     case LOC_CONST:
00993       printf_filtered ("constant %s (value %s) will not be collected.\n",
00994                        SYMBOL_PRINT_NAME (sym), plongest (SYMBOL_VALUE (sym)));
00995       break;
00996     case LOC_STATIC:
00997       offset = SYMBOL_VALUE_ADDRESS (sym);
00998       if (info_verbose)
00999         {
01000           char tmp[40];
01001 
01002           sprintf_vma (tmp, offset);
01003           printf_filtered ("LOC_STATIC %s: collect %ld bytes at %s.\n",
01004                            SYMBOL_PRINT_NAME (sym), len,
01005                            tmp /* address */);
01006         }
01007       /* A struct may be a C++ class with static fields, go to general
01008          expression handling.  */
01009       if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT)
01010         treat_as_expr = 1;
01011       else
01012         add_memrange (collect, memrange_absolute, offset, len);
01013       break;
01014     case LOC_REGISTER:
01015       reg = SYMBOL_REGISTER_OPS (sym)->register_number (sym, gdbarch);
01016       if (info_verbose)
01017         printf_filtered ("LOC_REG[parm] %s: ", 
01018                          SYMBOL_PRINT_NAME (sym));
01019       add_register (collect, reg);
01020       /* Check for doubles stored in two registers.  */
01021       /* FIXME: how about larger types stored in 3 or more regs?  */
01022       if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FLT &&
01023           len > register_size (gdbarch, reg))
01024         add_register (collect, reg + 1);
01025       break;
01026     case LOC_REF_ARG:
01027       printf_filtered ("Sorry, don't know how to do LOC_REF_ARG yet.\n");
01028       printf_filtered ("       (will not collect %s)\n",
01029                        SYMBOL_PRINT_NAME (sym));
01030       break;
01031     case LOC_ARG:
01032       reg = frame_regno;
01033       offset = frame_offset + SYMBOL_VALUE (sym);
01034       if (info_verbose)
01035         {
01036           printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset ",
01037                            SYMBOL_PRINT_NAME (sym), len);
01038           printf_vma (offset);
01039           printf_filtered (" from frame ptr reg %d\n", reg);
01040         }
01041       add_memrange (collect, reg, offset, len);
01042       break;
01043     case LOC_REGPARM_ADDR:
01044       reg = SYMBOL_VALUE (sym);
01045       offset = 0;
01046       if (info_verbose)
01047         {
01048           printf_filtered ("LOC_REGPARM_ADDR %s: Collect %ld bytes at offset ",
01049                            SYMBOL_PRINT_NAME (sym), len);
01050           printf_vma (offset);
01051           printf_filtered (" from reg %d\n", reg);
01052         }
01053       add_memrange (collect, reg, offset, len);
01054       break;
01055     case LOC_LOCAL:
01056       reg = frame_regno;
01057       offset = frame_offset + SYMBOL_VALUE (sym);
01058       if (info_verbose)
01059         {
01060           printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset ",
01061                            SYMBOL_PRINT_NAME (sym), len);
01062           printf_vma (offset);
01063           printf_filtered (" from frame ptr reg %d\n", reg);
01064         }
01065       add_memrange (collect, reg, offset, len);
01066       break;
01067 
01068     case LOC_UNRESOLVED:
01069       treat_as_expr = 1;
01070       break;
01071 
01072     case LOC_OPTIMIZED_OUT:
01073       printf_filtered ("%s has been optimized out of existence.\n",
01074                        SYMBOL_PRINT_NAME (sym));
01075       break;
01076 
01077     case LOC_COMPUTED:
01078       treat_as_expr = 1;
01079       break;
01080     }
01081 
01082   /* Expressions are the most general case.  */
01083   if (treat_as_expr)
01084     {
01085       struct agent_expr *aexpr;
01086       struct cleanup *old_chain1 = NULL;
01087 
01088       aexpr = gen_trace_for_var (scope, gdbarch, sym, trace_string);
01089 
01090       /* It can happen that the symbol is recorded as a computed
01091          location, but it's been optimized away and doesn't actually
01092          have a location expression.  */
01093       if (!aexpr)
01094         {
01095           printf_filtered ("%s has been optimized out of existence.\n",
01096                            SYMBOL_PRINT_NAME (sym));
01097           return;
01098         }
01099 
01100       old_chain1 = make_cleanup_free_agent_expr (aexpr);
01101 
01102       ax_reqs (aexpr);
01103 
01104       report_agent_reqs_errors (aexpr);
01105 
01106       discard_cleanups (old_chain1);
01107       add_aexpr (collect, aexpr);
01108 
01109       /* Take care of the registers.  */
01110       if (aexpr->reg_mask_len > 0)
01111         {
01112           int ndx1, ndx2;
01113 
01114           for (ndx1 = 0; ndx1 < aexpr->reg_mask_len; ndx1++)
01115             {
01116               QUIT;     /* Allow user to bail out with ^C.  */
01117               if (aexpr->reg_mask[ndx1] != 0)
01118                 {
01119                   /* Assume chars have 8 bits.  */
01120                   for (ndx2 = 0; ndx2 < 8; ndx2++)
01121                     if (aexpr->reg_mask[ndx1] & (1 << ndx2))
01122                       /* It's used -- record it.  */
01123                       add_register (collect, ndx1 * 8 + ndx2);
01124                 }
01125             }
01126         }
01127     }
01128 }
01129 
01130 /* Data to be passed around in the calls to the locals and args
01131    iterators.  */
01132 
01133 struct add_local_symbols_data
01134 {
01135   struct collection_list *collect;
01136   struct gdbarch *gdbarch;
01137   CORE_ADDR pc;
01138   long frame_regno;
01139   long frame_offset;
01140   int count;
01141   int trace_string;
01142 };
01143 
01144 /* The callback for the locals and args iterators.  */
01145 
01146 static void
01147 do_collect_symbol (const char *print_name,
01148                    struct symbol *sym,
01149                    void *cb_data)
01150 {
01151   struct add_local_symbols_data *p = cb_data;
01152 
01153   collect_symbol (p->collect, sym, p->gdbarch, p->frame_regno,
01154                   p->frame_offset, p->pc, p->trace_string);
01155   p->count++;
01156 
01157   VEC_safe_push (char_ptr, p->collect->wholly_collected,
01158                  xstrdup (print_name));
01159 }
01160 
01161 /* Add all locals (or args) symbols to collection list.  */
01162 static void
01163 add_local_symbols (struct collection_list *collect,
01164                    struct gdbarch *gdbarch, CORE_ADDR pc,
01165                    long frame_regno, long frame_offset, int type,
01166                    int trace_string)
01167 {
01168   struct block *block;
01169   struct add_local_symbols_data cb_data;
01170 
01171   cb_data.collect = collect;
01172   cb_data.gdbarch = gdbarch;
01173   cb_data.pc = pc;
01174   cb_data.frame_regno = frame_regno;
01175   cb_data.frame_offset = frame_offset;
01176   cb_data.count = 0;
01177   cb_data.trace_string = trace_string;
01178 
01179   if (type == 'L')
01180     {
01181       block = block_for_pc (pc);
01182       if (block == NULL)
01183         {
01184           warning (_("Can't collect locals; "
01185                      "no symbol table info available.\n"));
01186           return;
01187         }
01188 
01189       iterate_over_block_local_vars (block, do_collect_symbol, &cb_data);
01190       if (cb_data.count == 0)
01191         warning (_("No locals found in scope."));
01192     }
01193   else
01194     {
01195       pc = get_pc_function_start (pc);
01196       block = block_for_pc (pc);
01197       if (block == NULL)
01198         {
01199           warning (_("Can't collect args; no symbol table info available."));
01200           return;
01201         }
01202 
01203       iterate_over_block_arg_vars (block, do_collect_symbol, &cb_data);
01204       if (cb_data.count == 0)
01205         warning (_("No args found in scope."));
01206     }
01207 }
01208 
01209 static void
01210 add_static_trace_data (struct collection_list *collection)
01211 {
01212   if (info_verbose)
01213     printf_filtered ("collect static trace data\n");
01214   collection->strace_data = 1;
01215 }
01216 
01217 /* worker function */
01218 static void
01219 clear_collection_list (struct collection_list *list)
01220 {
01221   int ndx;
01222 
01223   list->next_memrange = 0;
01224   for (ndx = 0; ndx < list->next_aexpr_elt; ndx++)
01225     {
01226       free_agent_expr (list->aexpr_list[ndx]);
01227       list->aexpr_list[ndx] = NULL;
01228     }
01229   list->next_aexpr_elt = 0;
01230   memset (list->regs_mask, 0, sizeof (list->regs_mask));
01231   list->strace_data = 0;
01232 
01233   xfree (list->aexpr_list);
01234   xfree (list->list);
01235 
01236   VEC_free (char_ptr, list->wholly_collected);
01237   VEC_free (char_ptr, list->computed);
01238 }
01239 
01240 /* A cleanup wrapper for function clear_collection_list.  */
01241 
01242 static void
01243 do_clear_collection_list (void *list)
01244 {
01245   struct collection_list *l = list;
01246 
01247   clear_collection_list (l);
01248 }
01249 
01250 /* Initialize collection_list CLIST.  */
01251 
01252 static void
01253 init_collection_list (struct collection_list *clist)
01254 {
01255   memset (clist, 0, sizeof *clist);
01256 
01257   clist->listsize = 128;
01258   clist->list = xcalloc (clist->listsize,
01259                          sizeof (struct memrange));
01260 
01261   clist->aexpr_listsize = 128;
01262   clist->aexpr_list = xcalloc (clist->aexpr_listsize,
01263                                sizeof (struct agent_expr *));
01264 }
01265 
01266 /* Reduce a collection list to string form (for gdb protocol).  */
01267 static char **
01268 stringify_collection_list (struct collection_list *list)
01269 {
01270   char temp_buf[2048];
01271   char tmp2[40];
01272   int count;
01273   int ndx = 0;
01274   char *(*str_list)[];
01275   char *end;
01276   long i;
01277 
01278   count = 1 + 1 + list->next_memrange + list->next_aexpr_elt + 1;
01279   str_list = (char *(*)[]) xmalloc (count * sizeof (char *));
01280 
01281   if (list->strace_data)
01282     {
01283       if (info_verbose)
01284         printf_filtered ("\nCollecting static trace data\n");
01285       end = temp_buf;
01286       *end++ = 'L';
01287       (*str_list)[ndx] = savestring (temp_buf, end - temp_buf);
01288       ndx++;
01289     }
01290 
01291   for (i = sizeof (list->regs_mask) - 1; i > 0; i--)
01292     if (list->regs_mask[i] != 0)    /* Skip leading zeroes in regs_mask.  */
01293       break;
01294   if (list->regs_mask[i] != 0)  /* Prepare to send regs_mask to the stub.  */
01295     {
01296       if (info_verbose)
01297         printf_filtered ("\nCollecting registers (mask): 0x");
01298       end = temp_buf;
01299       *end++ = 'R';
01300       for (; i >= 0; i--)
01301         {
01302           QUIT;                 /* Allow user to bail out with ^C.  */
01303           if (info_verbose)
01304             printf_filtered ("%02X", list->regs_mask[i]);
01305           sprintf (end, "%02X", list->regs_mask[i]);
01306           end += 2;
01307         }
01308       (*str_list)[ndx] = xstrdup (temp_buf);
01309       ndx++;
01310     }
01311   if (info_verbose)
01312     printf_filtered ("\n");
01313   if (list->next_memrange > 0 && info_verbose)
01314     printf_filtered ("Collecting memranges: \n");
01315   for (i = 0, count = 0, end = temp_buf; i < list->next_memrange; i++)
01316     {
01317       QUIT;                     /* Allow user to bail out with ^C.  */
01318       sprintf_vma (tmp2, list->list[i].start);
01319       if (info_verbose)
01320         {
01321           printf_filtered ("(%d, %s, %ld)\n", 
01322                            list->list[i].type, 
01323                            tmp2, 
01324                            (long) (list->list[i].end - list->list[i].start));
01325         }
01326       if (count + 27 > MAX_AGENT_EXPR_LEN)
01327         {
01328           (*str_list)[ndx] = savestring (temp_buf, count);
01329           ndx++;
01330           count = 0;
01331           end = temp_buf;
01332         }
01333 
01334       {
01335         bfd_signed_vma length = list->list[i].end - list->list[i].start;
01336 
01337         /* The "%X" conversion specifier expects an unsigned argument,
01338            so passing -1 (memrange_absolute) to it directly gives you
01339            "FFFFFFFF" (or more, depending on sizeof (unsigned)).
01340            Special-case it.  */
01341         if (list->list[i].type == memrange_absolute)
01342           sprintf (end, "M-1,%s,%lX", tmp2, (long) length);
01343         else
01344           sprintf (end, "M%X,%s,%lX", list->list[i].type, tmp2, (long) length);
01345       }
01346 
01347       count += strlen (end);
01348       end = temp_buf + count;
01349     }
01350 
01351   for (i = 0; i < list->next_aexpr_elt; i++)
01352     {
01353       QUIT;                     /* Allow user to bail out with ^C.  */
01354       if ((count + 10 + 2 * list->aexpr_list[i]->len) > MAX_AGENT_EXPR_LEN)
01355         {
01356           (*str_list)[ndx] = savestring (temp_buf, count);
01357           ndx++;
01358           count = 0;
01359           end = temp_buf;
01360         }
01361       sprintf (end, "X%08X,", list->aexpr_list[i]->len);
01362       end += 10;                /* 'X' + 8 hex digits + ',' */
01363       count += 10;
01364 
01365       end = mem2hex (list->aexpr_list[i]->buf, 
01366                      end, list->aexpr_list[i]->len);
01367       count += 2 * list->aexpr_list[i]->len;
01368     }
01369 
01370   if (count != 0)
01371     {
01372       (*str_list)[ndx] = savestring (temp_buf, count);
01373       ndx++;
01374       count = 0;
01375       end = temp_buf;
01376     }
01377   (*str_list)[ndx] = NULL;
01378 
01379   if (ndx == 0)
01380     {
01381       xfree (str_list);
01382       return NULL;
01383     }
01384   else
01385     return *str_list;
01386 }
01387 
01388 /* Add the printed expression EXP to *LIST.  */
01389 
01390 static void
01391 append_exp (struct expression *exp, VEC(char_ptr) **list)
01392 {
01393   struct ui_file *tmp_stream = mem_fileopen ();
01394   char *text;
01395 
01396   print_expression (exp, tmp_stream);
01397 
01398   text = ui_file_xstrdup (tmp_stream, NULL);
01399 
01400   VEC_safe_push (char_ptr, *list, text);
01401   ui_file_delete (tmp_stream);
01402 }
01403 
01404 static void
01405 encode_actions_1 (struct command_line *action,
01406                   struct bp_location *tloc,
01407                   int frame_reg,
01408                   LONGEST frame_offset,
01409                   struct collection_list *collect,
01410                   struct collection_list *stepping_list)
01411 {
01412   const char *action_exp;
01413   struct expression *exp = NULL;
01414   int i;
01415   struct value *tempval;
01416   struct cmd_list_element *cmd;
01417   struct agent_expr *aexpr;
01418 
01419   for (; action; action = action->next)
01420     {
01421       QUIT;                     /* Allow user to bail out with ^C.  */
01422       action_exp = action->line;
01423       action_exp = skip_spaces_const (action_exp);
01424 
01425       cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
01426       if (cmd == 0)
01427         error (_("Bad action list item: %s"), action_exp);
01428 
01429       if (cmd_cfunc_eq (cmd, collect_pseudocommand))
01430         {
01431           int trace_string = 0;
01432 
01433           if (*action_exp == '/')
01434             action_exp = decode_agent_options (action_exp, &trace_string);
01435 
01436           do
01437             {                   /* Repeat over a comma-separated list.  */
01438               QUIT;             /* Allow user to bail out with ^C.  */
01439               action_exp = skip_spaces_const (action_exp);
01440 
01441               if (0 == strncasecmp ("$reg", action_exp, 4))
01442                 {
01443                   for (i = 0; i < gdbarch_num_regs (tloc->gdbarch); i++)
01444                     add_register (collect, i);
01445                   action_exp = strchr (action_exp, ',');        /* more? */
01446                 }
01447               else if (0 == strncasecmp ("$arg", action_exp, 4))
01448                 {
01449                   add_local_symbols (collect,
01450                                      tloc->gdbarch,
01451                                      tloc->address,
01452                                      frame_reg,
01453                                      frame_offset,
01454                                      'A',
01455                                      trace_string);
01456                   action_exp = strchr (action_exp, ',');        /* more? */
01457                 }
01458               else if (0 == strncasecmp ("$loc", action_exp, 4))
01459                 {
01460                   add_local_symbols (collect,
01461                                      tloc->gdbarch,
01462                                      tloc->address,
01463                                      frame_reg,
01464                                      frame_offset,
01465                                      'L',
01466                                      trace_string);
01467                   action_exp = strchr (action_exp, ',');        /* more? */
01468                 }
01469               else if (0 == strncasecmp ("$_ret", action_exp, 5))
01470                 {
01471                   struct cleanup *old_chain1 = NULL;
01472 
01473                   aexpr = gen_trace_for_return_address (tloc->address,
01474                                                         tloc->gdbarch,
01475                                                         trace_string);
01476 
01477                   old_chain1 = make_cleanup_free_agent_expr (aexpr);
01478 
01479                   ax_reqs (aexpr);
01480                   report_agent_reqs_errors (aexpr);
01481 
01482                   discard_cleanups (old_chain1);
01483                   add_aexpr (collect, aexpr);
01484 
01485                   /* take care of the registers */
01486                   if (aexpr->reg_mask_len > 0)
01487                     {
01488                       int ndx1, ndx2;
01489 
01490                       for (ndx1 = 0; ndx1 < aexpr->reg_mask_len; ndx1++)
01491                         {
01492                           QUIT; /* allow user to bail out with ^C */
01493                           if (aexpr->reg_mask[ndx1] != 0)
01494                             {
01495                               /* assume chars have 8 bits */
01496                               for (ndx2 = 0; ndx2 < 8; ndx2++)
01497                                 if (aexpr->reg_mask[ndx1] & (1 << ndx2))
01498                                   /* it's used -- record it */
01499                                   add_register (collect, 
01500                                                 ndx1 * 8 + ndx2);
01501                             }
01502                         }
01503                     }
01504 
01505                   action_exp = strchr (action_exp, ',');        /* more? */
01506                 }
01507               else if (0 == strncasecmp ("$_sdata", action_exp, 7))
01508                 {
01509                   add_static_trace_data (collect);
01510                   action_exp = strchr (action_exp, ',');        /* more? */
01511                 }
01512               else
01513                 {
01514                   unsigned long addr;
01515                   struct cleanup *old_chain = NULL;
01516                   struct cleanup *old_chain1 = NULL;
01517 
01518                   exp = parse_exp_1 (&action_exp, tloc->address,
01519                                      block_for_pc (tloc->address), 1);
01520                   old_chain = make_cleanup (free_current_contents, &exp);
01521 
01522                   switch (exp->elts[0].opcode)
01523                     {
01524                     case OP_REGISTER:
01525                       {
01526                         const char *name = &exp->elts[2].string;
01527 
01528                         i = user_reg_map_name_to_regnum (tloc->gdbarch,
01529                                                          name, strlen (name));
01530                         if (i == -1)
01531                           internal_error (__FILE__, __LINE__,
01532                                           _("Register $%s not available"),
01533                                           name);
01534                         if (info_verbose)
01535                           printf_filtered ("OP_REGISTER: ");
01536                         add_register (collect, i);
01537                         break;
01538                       }
01539 
01540                     case UNOP_MEMVAL:
01541                       /* Safe because we know it's a simple expression.  */
01542                       tempval = evaluate_expression (exp);
01543                       addr = value_address (tempval);
01544                       /* Initialize the TYPE_LENGTH if it is a typedef.  */
01545                       check_typedef (exp->elts[1].type);
01546                       add_memrange (collect, memrange_absolute, addr,
01547                                     TYPE_LENGTH (exp->elts[1].type));
01548                       append_exp (exp, &collect->computed);
01549                       break;
01550 
01551                     case OP_VAR_VALUE:
01552                       {
01553                         struct symbol *sym = exp->elts[2].symbol;
01554                         char_ptr name = (char_ptr) SYMBOL_NATURAL_NAME (sym);
01555 
01556                         collect_symbol (collect,
01557                                         exp->elts[2].symbol,
01558                                         tloc->gdbarch,
01559                                         frame_reg,
01560                                         frame_offset,
01561                                         tloc->address,
01562                                         trace_string);
01563                         VEC_safe_push (char_ptr,
01564                                        collect->wholly_collected,
01565                                        name);
01566                       }
01567                       break;
01568 
01569                     default:    /* Full-fledged expression.  */
01570                       aexpr = gen_trace_for_expr (tloc->address, exp,
01571                                                   trace_string);
01572 
01573                       old_chain1 = make_cleanup_free_agent_expr (aexpr);
01574 
01575                       ax_reqs (aexpr);
01576 
01577                       report_agent_reqs_errors (aexpr);
01578 
01579                       discard_cleanups (old_chain1);
01580                       add_aexpr (collect, aexpr);
01581 
01582                       /* Take care of the registers.  */
01583                       if (aexpr->reg_mask_len > 0)
01584                         {
01585                           int ndx1;
01586                           int ndx2;
01587 
01588                           for (ndx1 = 0; ndx1 < aexpr->reg_mask_len; ndx1++)
01589                             {
01590                               QUIT;     /* Allow user to bail out with ^C.  */
01591                               if (aexpr->reg_mask[ndx1] != 0)
01592                                 {
01593                                   /* Assume chars have 8 bits.  */
01594                                   for (ndx2 = 0; ndx2 < 8; ndx2++)
01595                                     if (aexpr->reg_mask[ndx1] & (1 << ndx2))
01596                                       /* It's used -- record it.  */
01597                                       add_register (collect, 
01598                                                     ndx1 * 8 + ndx2);
01599                                 }
01600                             }
01601                         }
01602 
01603                       append_exp (exp, &collect->computed);
01604                       break;
01605                     }           /* switch */
01606                   do_cleanups (old_chain);
01607                 }               /* do */
01608             }
01609           while (action_exp && *action_exp++ == ',');
01610         }                       /* if */
01611       else if (cmd_cfunc_eq (cmd, teval_pseudocommand))
01612         {
01613           do
01614             {                   /* Repeat over a comma-separated list.  */
01615               QUIT;             /* Allow user to bail out with ^C.  */
01616               action_exp = skip_spaces_const (action_exp);
01617 
01618                 {
01619                   struct cleanup *old_chain = NULL;
01620                   struct cleanup *old_chain1 = NULL;
01621 
01622                   exp = parse_exp_1 (&action_exp, tloc->address,
01623                                      block_for_pc (tloc->address), 1);
01624                   old_chain = make_cleanup (free_current_contents, &exp);
01625 
01626                   aexpr = gen_eval_for_expr (tloc->address, exp);
01627                   old_chain1 = make_cleanup_free_agent_expr (aexpr);
01628 
01629                   ax_reqs (aexpr);
01630                   report_agent_reqs_errors (aexpr);
01631 
01632                   discard_cleanups (old_chain1);
01633                   /* Even though we're not officially collecting, add
01634                      to the collect list anyway.  */
01635                   add_aexpr (collect, aexpr);
01636 
01637                   do_cleanups (old_chain);
01638                 }               /* do */
01639             }
01640           while (action_exp && *action_exp++ == ',');
01641         }                       /* if */
01642       else if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand))
01643         {
01644           /* We check against nested while-stepping when setting
01645              breakpoint action, so no way to run into nested
01646              here.  */
01647           gdb_assert (stepping_list);
01648 
01649           encode_actions_1 (action->body_list[0], tloc, frame_reg,
01650                             frame_offset, stepping_list, NULL);
01651         }
01652       else
01653         error (_("Invalid tracepoint command '%s'"), action->line);
01654     }                           /* for */
01655 }
01656 
01657 /* Encode actions of tracepoint TLOC->owner and fill TRACEPOINT_LIST
01658    and STEPPING_LIST.  Return a cleanup pointer to clean up both
01659    TRACEPOINT_LIST and STEPPING_LIST.  */
01660 
01661 struct cleanup *
01662 encode_actions_and_make_cleanup (struct bp_location *tloc,
01663                                  struct collection_list *tracepoint_list,
01664                                  struct collection_list *stepping_list)
01665 {
01666   char *default_collect_line = NULL;
01667   struct command_line *actions;
01668   struct command_line *default_collect_action = NULL;
01669   int frame_reg;
01670   LONGEST frame_offset;
01671   struct cleanup *back_to, *return_chain;
01672 
01673   return_chain = make_cleanup (null_cleanup, NULL);
01674   init_collection_list (tracepoint_list);
01675   init_collection_list (stepping_list);
01676 
01677   make_cleanup (do_clear_collection_list, tracepoint_list);
01678   make_cleanup (do_clear_collection_list, stepping_list);
01679 
01680   back_to = make_cleanup (null_cleanup, NULL);
01681   gdbarch_virtual_frame_pointer (tloc->gdbarch,
01682                                  tloc->address, &frame_reg, &frame_offset);
01683 
01684   actions = all_tracepoint_actions_and_cleanup (tloc->owner);
01685 
01686   encode_actions_1 (actions, tloc, frame_reg, frame_offset,
01687                     tracepoint_list, stepping_list);
01688 
01689   memrange_sortmerge (tracepoint_list);
01690   memrange_sortmerge (stepping_list);
01691 
01692   do_cleanups (back_to);
01693   return return_chain;
01694 }
01695 
01696 /* Render all actions into gdb protocol.  */
01697 
01698 void
01699 encode_actions_rsp (struct bp_location *tloc, char ***tdp_actions,
01700                     char ***stepping_actions)
01701 {
01702   struct collection_list tracepoint_list, stepping_list;
01703   struct cleanup *cleanup;
01704 
01705   *tdp_actions = NULL;
01706   *stepping_actions = NULL;
01707 
01708   cleanup = encode_actions_and_make_cleanup (tloc, &tracepoint_list,
01709                                              &stepping_list);
01710 
01711   *tdp_actions = stringify_collection_list (&tracepoint_list);
01712   *stepping_actions = stringify_collection_list (&stepping_list);
01713 
01714   do_cleanups (cleanup);
01715 }
01716 
01717 static void
01718 add_aexpr (struct collection_list *collect, struct agent_expr *aexpr)
01719 {
01720   if (collect->next_aexpr_elt >= collect->aexpr_listsize)
01721     {
01722       collect->aexpr_list =
01723         xrealloc (collect->aexpr_list,
01724                   2 * collect->aexpr_listsize * sizeof (struct agent_expr *));
01725       collect->aexpr_listsize *= 2;
01726     }
01727   collect->aexpr_list[collect->next_aexpr_elt] = aexpr;
01728   collect->next_aexpr_elt++;
01729 }
01730 
01731 static void
01732 process_tracepoint_on_disconnect (void)
01733 {
01734   VEC(breakpoint_p) *tp_vec = NULL;
01735   int ix;
01736   struct breakpoint *b;
01737   int has_pending_p = 0;
01738 
01739   /* Check whether we still have pending tracepoint.  If we have, warn the
01740      user that pending tracepoint will no longer work.  */
01741   tp_vec = all_tracepoints ();
01742   for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, b); ix++)
01743     {
01744       if (b->loc == NULL)
01745         {
01746           has_pending_p = 1;
01747           break;
01748         }
01749       else
01750         {
01751           struct bp_location *loc1;
01752 
01753           for (loc1 = b->loc; loc1; loc1 = loc1->next)
01754             {
01755               if (loc1->shlib_disabled)
01756                 {
01757                   has_pending_p = 1;
01758                   break;
01759                 }
01760             }
01761 
01762           if (has_pending_p)
01763             break;
01764         }
01765     }
01766   VEC_free (breakpoint_p, tp_vec);
01767 
01768   if (has_pending_p)
01769     warning (_("Pending tracepoints will not be resolved while"
01770                " GDB is disconnected\n"));
01771 }
01772 
01773 /* Reset local state of tracing.  */
01774 
01775 void
01776 trace_reset_local_state (void)
01777 {
01778   set_traceframe_num (-1);
01779   set_tracepoint_num (-1);
01780   set_traceframe_context (NULL);
01781   clear_traceframe_info ();
01782 }
01783 
01784 void
01785 start_tracing (char *notes)
01786 {
01787   VEC(breakpoint_p) *tp_vec = NULL;
01788   int ix;
01789   struct breakpoint *b;
01790   struct trace_state_variable *tsv;
01791   int any_enabled = 0, num_to_download = 0;
01792   int ret;
01793 
01794   tp_vec = all_tracepoints ();
01795 
01796   /* No point in tracing without any tracepoints...  */
01797   if (VEC_length (breakpoint_p, tp_vec) == 0)
01798     {
01799       VEC_free (breakpoint_p, tp_vec);
01800       error (_("No tracepoints defined, not starting trace"));
01801     }
01802 
01803   for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, b); ix++)
01804     {
01805       struct tracepoint *t = (struct tracepoint *) b;
01806       struct bp_location *loc;
01807 
01808       if (b->enable_state == bp_enabled)
01809         any_enabled = 1;
01810 
01811       if ((b->type == bp_fast_tracepoint
01812            ? may_insert_fast_tracepoints
01813            : may_insert_tracepoints))
01814         ++num_to_download;
01815       else
01816         warning (_("May not insert %stracepoints, skipping tracepoint %d"),
01817                  (b->type == bp_fast_tracepoint ? "fast " : ""), b->number);
01818     }
01819 
01820   if (!any_enabled)
01821     {
01822       if (target_supports_enable_disable_tracepoint ())
01823         warning (_("No tracepoints enabled"));
01824       else
01825         {
01826           /* No point in tracing with only disabled tracepoints that
01827              cannot be re-enabled.  */
01828           VEC_free (breakpoint_p, tp_vec);
01829           error (_("No tracepoints enabled, not starting trace"));
01830         }
01831     }
01832 
01833   if (num_to_download <= 0)
01834     {
01835       VEC_free (breakpoint_p, tp_vec);
01836       error (_("No tracepoints that may be downloaded, not starting trace"));
01837     }
01838 
01839   target_trace_init ();
01840 
01841   for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, b); ix++)
01842     {
01843       struct tracepoint *t = (struct tracepoint *) b;
01844       struct bp_location *loc;
01845       int bp_location_downloaded = 0;
01846 
01847       /* Clear `inserted' flag.  */
01848       for (loc = b->loc; loc; loc = loc->next)
01849         loc->inserted = 0;
01850 
01851       if ((b->type == bp_fast_tracepoint
01852            ? !may_insert_fast_tracepoints
01853            : !may_insert_tracepoints))
01854         continue;
01855 
01856       t->number_on_target = 0;
01857 
01858       for (loc = b->loc; loc; loc = loc->next)
01859         {
01860           /* Since tracepoint locations are never duplicated, `inserted'
01861              flag should be zero.  */
01862           gdb_assert (!loc->inserted);
01863 
01864           target_download_tracepoint (loc);
01865 
01866           loc->inserted = 1;
01867           bp_location_downloaded = 1;
01868         }
01869 
01870       t->number_on_target = b->number;
01871 
01872       for (loc = b->loc; loc; loc = loc->next)
01873         if (loc->probe != NULL)
01874           loc->probe->pops->set_semaphore (loc->probe, loc->gdbarch);
01875 
01876       if (bp_location_downloaded)
01877         observer_notify_breakpoint_modified (b);
01878     }
01879   VEC_free (breakpoint_p, tp_vec);
01880 
01881   /* Send down all the trace state variables too.  */
01882   for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
01883     {
01884       target_download_trace_state_variable (tsv);
01885     }
01886   
01887   /* Tell target to treat text-like sections as transparent.  */
01888   target_trace_set_readonly_regions ();
01889   /* Set some mode flags.  */
01890   target_set_disconnected_tracing (disconnected_tracing);
01891   target_set_circular_trace_buffer (circular_trace_buffer);
01892   target_set_trace_buffer_size (trace_buffer_size);
01893 
01894   if (!notes)
01895     notes = trace_notes;
01896   ret = target_set_trace_notes (trace_user, notes, NULL);
01897 
01898   if (!ret && (trace_user || notes))
01899     warning (_("Target does not support trace user/notes, info ignored"));
01900 
01901   /* Now insert traps and begin collecting data.  */
01902   target_trace_start ();
01903 
01904   /* Reset our local state.  */
01905   trace_reset_local_state ();
01906   current_trace_status()->running = 1;
01907 }
01908 
01909 /* The tstart command requests the target to start a new trace run.
01910    The command passes any arguments it has to the target verbatim, as
01911    an optional "trace note".  This is useful as for instance a warning
01912    to other users if the trace runs disconnected, and you don't want
01913    anybody else messing with the target.  */
01914 
01915 static void
01916 trace_start_command (char *args, int from_tty)
01917 {
01918   dont_repeat ();       /* Like "run", dangerous to repeat accidentally.  */
01919 
01920   if (current_trace_status ()->running)
01921     {
01922       if (from_tty
01923           && !query (_("A trace is running already.  Start a new run? ")))
01924         error (_("New trace run not started."));
01925     }
01926 
01927   start_tracing (args);
01928 }
01929 
01930 /* The tstop command stops the tracing run.  The command passes any
01931    supplied arguments to the target verbatim as a "stop note"; if the
01932    target supports trace notes, then it will be reported back as part
01933    of the trace run's status.  */
01934 
01935 static void
01936 trace_stop_command (char *args, int from_tty)
01937 {
01938   if (!current_trace_status ()->running)
01939     error (_("Trace is not running."));
01940 
01941   stop_tracing (args);
01942 }
01943 
01944 void
01945 stop_tracing (char *note)
01946 {
01947   int ret;
01948   VEC(breakpoint_p) *tp_vec = NULL;
01949   int ix;
01950   struct breakpoint *t;
01951 
01952   target_trace_stop ();
01953 
01954   tp_vec = all_tracepoints ();
01955   for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, t); ix++)
01956     {
01957       struct bp_location *loc;
01958 
01959       if ((t->type == bp_fast_tracepoint
01960            ? !may_insert_fast_tracepoints
01961            : !may_insert_tracepoints))
01962         continue;
01963 
01964       for (loc = t->loc; loc; loc = loc->next)
01965         {
01966           /* GDB can be totally absent in some disconnected trace scenarios,
01967              but we don't really care if this semaphore goes out of sync.
01968              That's why we are decrementing it here, but not taking care
01969              in other places.  */
01970           if (loc->probe != NULL)
01971             loc->probe->pops->clear_semaphore (loc->probe, loc->gdbarch);
01972         }
01973     }
01974 
01975   VEC_free (breakpoint_p, tp_vec);
01976 
01977   if (!note)
01978     note = trace_stop_notes;
01979   ret = target_set_trace_notes (NULL, NULL, note);
01980 
01981   if (!ret && note)
01982     warning (_("Target does not support trace notes, note ignored"));
01983 
01984   /* Should change in response to reply?  */
01985   current_trace_status ()->running = 0;
01986 }
01987 
01988 /* tstatus command */
01989 static void
01990 trace_status_command (char *args, int from_tty)
01991 {
01992   struct trace_status *ts = current_trace_status ();
01993   int status, ix;
01994   VEC(breakpoint_p) *tp_vec = NULL;
01995   struct breakpoint *t;
01996   
01997   status = target_get_trace_status (ts);
01998 
01999   if (status == -1)
02000     {
02001       if (ts->filename != NULL)
02002         printf_filtered (_("Using a trace file.\n"));
02003       else
02004         {
02005           printf_filtered (_("Trace can not be run on this target.\n"));
02006           return;
02007         }
02008     }
02009 
02010   if (!ts->running_known)
02011     {
02012       printf_filtered (_("Run/stop status is unknown.\n"));
02013     }
02014   else if (ts->running)
02015     {
02016       printf_filtered (_("Trace is running on the target.\n"));
02017     }
02018   else
02019     {
02020       switch (ts->stop_reason)
02021         {
02022         case trace_never_run:
02023           printf_filtered (_("No trace has been run on the target.\n"));
02024           break;
02025         case tstop_command:
02026           if (ts->stop_desc)
02027             printf_filtered (_("Trace stopped by a tstop command (%s).\n"),
02028                              ts->stop_desc);
02029           else
02030             printf_filtered (_("Trace stopped by a tstop command.\n"));
02031           break;
02032         case trace_buffer_full:
02033           printf_filtered (_("Trace stopped because the buffer was full.\n"));
02034           break;
02035         case trace_disconnected:
02036           printf_filtered (_("Trace stopped because of disconnection.\n"));
02037           break;
02038         case tracepoint_passcount:
02039           printf_filtered (_("Trace stopped by tracepoint %d.\n"),
02040                            ts->stopping_tracepoint);
02041           break;
02042         case tracepoint_error:
02043           if (ts->stopping_tracepoint)
02044             printf_filtered (_("Trace stopped by an "
02045                                "error (%s, tracepoint %d).\n"),
02046                              ts->stop_desc, ts->stopping_tracepoint);
02047           else
02048             printf_filtered (_("Trace stopped by an error (%s).\n"),
02049                              ts->stop_desc);
02050           break;
02051         case trace_stop_reason_unknown:
02052           printf_filtered (_("Trace stopped for an unknown reason.\n"));
02053           break;
02054         default:
02055           printf_filtered (_("Trace stopped for some other reason (%d).\n"),
02056                            ts->stop_reason);
02057           break;
02058         }
02059     }
02060 
02061   if (ts->traceframes_created >= 0
02062       && ts->traceframe_count != ts->traceframes_created)
02063     {
02064       printf_filtered (_("Buffer contains %d trace "
02065                          "frames (of %d created total).\n"),
02066                        ts->traceframe_count, ts->traceframes_created);
02067     }
02068   else if (ts->traceframe_count >= 0)
02069     {
02070       printf_filtered (_("Collected %d trace frames.\n"),
02071                        ts->traceframe_count);
02072     }
02073 
02074   if (ts->buffer_free >= 0)
02075     {
02076       if (ts->buffer_size >= 0)
02077         {
02078           printf_filtered (_("Trace buffer has %d bytes of %d bytes free"),
02079                            ts->buffer_free, ts->buffer_size);
02080           if (ts->buffer_size > 0)
02081             printf_filtered (_(" (%d%% full)"),
02082                              ((int) ((((long long) (ts->buffer_size
02083                                                     - ts->buffer_free)) * 100)
02084                                      / ts->buffer_size)));
02085           printf_filtered (_(".\n"));
02086         }
02087       else
02088         printf_filtered (_("Trace buffer has %d bytes free.\n"),
02089                          ts->buffer_free);
02090     }
02091 
02092   if (ts->disconnected_tracing)
02093     printf_filtered (_("Trace will continue if GDB disconnects.\n"));
02094   else
02095     printf_filtered (_("Trace will stop if GDB disconnects.\n"));
02096 
02097   if (ts->circular_buffer)
02098     printf_filtered (_("Trace buffer is circular.\n"));
02099 
02100   if (ts->user_name && strlen (ts->user_name) > 0)
02101     printf_filtered (_("Trace user is %s.\n"), ts->user_name);
02102 
02103   if (ts->notes && strlen (ts->notes) > 0)
02104     printf_filtered (_("Trace notes: %s.\n"), ts->notes);
02105 
02106   /* Now report on what we're doing with tfind.  */
02107   if (traceframe_number >= 0)
02108     printf_filtered (_("Looking at trace frame %d, tracepoint %d.\n"),
02109                      traceframe_number, tracepoint_number);
02110   else
02111     printf_filtered (_("Not looking at any trace frame.\n"));
02112 
02113   /* Report start/stop times if supplied.  */
02114   if (ts->start_time)
02115     {
02116       if (ts->stop_time)
02117         {
02118           LONGEST run_time = ts->stop_time - ts->start_time;
02119 
02120           /* Reporting a run time is more readable than two long numbers.  */
02121           printf_filtered (_("Trace started at %ld.%06ld secs, stopped %ld.%06ld secs later.\n"),
02122                            (long int) (ts->start_time / 1000000),
02123                            (long int) (ts->start_time % 1000000),
02124                            (long int) (run_time / 1000000),
02125                            (long int) (run_time % 1000000));
02126         }
02127       else
02128         printf_filtered (_("Trace started at %ld.%06ld secs.\n"),
02129                          (long int) (ts->start_time / 1000000),
02130                          (long int) (ts->start_time % 1000000));
02131     }
02132   else if (ts->stop_time)
02133     printf_filtered (_("Trace stopped at %ld.%06ld secs.\n"),
02134                      (long int) (ts->stop_time / 1000000),
02135                      (long int) (ts->stop_time % 1000000));
02136 
02137   /* Now report any per-tracepoint status available.  */
02138   tp_vec = all_tracepoints ();
02139 
02140   for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, t); ix++)
02141     target_get_tracepoint_status (t, NULL);
02142 
02143   VEC_free (breakpoint_p, tp_vec);
02144 }
02145 
02146 /* Report the trace status to uiout, in a way suitable for MI, and not
02147    suitable for CLI.  If ON_STOP is true, suppress a few fields that
02148    are not meaningful in the -trace-stop response.
02149 
02150    The implementation is essentially parallel to trace_status_command, but
02151    merging them will result in unreadable code.  */
02152 void
02153 trace_status_mi (int on_stop)
02154 {
02155   struct ui_out *uiout = current_uiout;
02156   struct trace_status *ts = current_trace_status ();
02157   int status;
02158 
02159   status = target_get_trace_status (ts);
02160 
02161   if (status == -1 && ts->filename == NULL)
02162     {
02163       ui_out_field_string (uiout, "supported", "0");
02164       return;
02165     }
02166 
02167   if (ts->filename != NULL)
02168     ui_out_field_string (uiout, "supported", "file");
02169   else if (!on_stop)
02170     ui_out_field_string (uiout, "supported", "1");
02171 
02172   if (ts->filename != NULL)
02173     ui_out_field_string (uiout, "trace-file", ts->filename);
02174 
02175   gdb_assert (ts->running_known);
02176 
02177   if (ts->running)
02178     {
02179       ui_out_field_string (uiout, "running", "1");
02180 
02181       /* Unlike CLI, do not show the state of 'disconnected-tracing' variable.
02182          Given that the frontend gets the status either on -trace-stop, or from
02183          -trace-status after re-connection, it does not seem like this
02184          information is necessary for anything.  It is not necessary for either
02185          figuring the vital state of the target nor for navigation of trace
02186          frames.  If the frontend wants to show the current state is some
02187          configure dialog, it can request the value when such dialog is
02188          invoked by the user.  */
02189     }
02190   else
02191     {
02192       char *stop_reason = NULL;
02193       int stopping_tracepoint = -1;
02194 
02195       if (!on_stop)
02196         ui_out_field_string (uiout, "running", "0");
02197 
02198       if (ts->stop_reason != trace_stop_reason_unknown)
02199         {
02200           switch (ts->stop_reason)
02201             {
02202             case tstop_command:
02203               stop_reason = "request";
02204               break;
02205             case trace_buffer_full:
02206               stop_reason = "overflow";
02207               break;
02208             case trace_disconnected:
02209               stop_reason = "disconnection";
02210               break;
02211             case tracepoint_passcount:
02212               stop_reason = "passcount";
02213               stopping_tracepoint = ts->stopping_tracepoint;
02214               break;
02215             case tracepoint_error:
02216               stop_reason = "error";
02217               stopping_tracepoint = ts->stopping_tracepoint;
02218               break;
02219             }
02220           
02221           if (stop_reason)
02222             {
02223               ui_out_field_string (uiout, "stop-reason", stop_reason);
02224               if (stopping_tracepoint != -1)
02225                 ui_out_field_int (uiout, "stopping-tracepoint",
02226                                   stopping_tracepoint);
02227               if (ts->stop_reason == tracepoint_error)
02228                 ui_out_field_string (uiout, "error-description",
02229                                      ts->stop_desc);
02230             }
02231         }
02232     }
02233 
02234   if (ts->traceframe_count != -1)
02235     ui_out_field_int (uiout, "frames", ts->traceframe_count);
02236   if (ts->traceframes_created != -1)
02237     ui_out_field_int (uiout, "frames-created", ts->traceframes_created);
02238   if (ts->buffer_size != -1)
02239     ui_out_field_int (uiout, "buffer-size", ts->buffer_size);
02240   if (ts->buffer_free != -1)
02241     ui_out_field_int (uiout, "buffer-free", ts->buffer_free);
02242 
02243   ui_out_field_int (uiout, "disconnected",  ts->disconnected_tracing);
02244   ui_out_field_int (uiout, "circular",  ts->circular_buffer);
02245 
02246   ui_out_field_string (uiout, "user-name", ts->user_name);
02247   ui_out_field_string (uiout, "notes", ts->notes);
02248 
02249   {
02250     char buf[100];
02251 
02252     xsnprintf (buf, sizeof buf, "%ld.%06ld",
02253                (long int) (ts->start_time / 1000000),
02254                (long int) (ts->start_time % 1000000));
02255     ui_out_field_string (uiout, "start-time", buf);
02256     xsnprintf (buf, sizeof buf, "%ld.%06ld",
02257                (long int) (ts->stop_time / 1000000),
02258                (long int) (ts->stop_time % 1000000));
02259     ui_out_field_string (uiout, "stop-time", buf);
02260   }
02261 }
02262 
02263 /* Check if a trace run is ongoing.  If so, and FROM_TTY, query the
02264    user if she really wants to detach.  */
02265 
02266 void
02267 query_if_trace_running (int from_tty)
02268 {
02269   if (!from_tty)
02270     return;
02271 
02272   /* It can happen that the target that was tracing went away on its
02273      own, and we didn't notice.  Get a status update, and if the
02274      current target doesn't even do tracing, then assume it's not
02275      running anymore.  */
02276   if (target_get_trace_status (current_trace_status ()) < 0)
02277     current_trace_status ()->running = 0;
02278 
02279   /* If running interactively, give the user the option to cancel and
02280      then decide what to do differently with the run.  Scripts are
02281      just going to disconnect and let the target deal with it,
02282      according to how it's been instructed previously via
02283      disconnected-tracing.  */
02284   if (current_trace_status ()->running)
02285     {
02286       process_tracepoint_on_disconnect ();
02287 
02288       if (current_trace_status ()->disconnected_tracing)
02289         {
02290           if (!query (_("Trace is running and will "
02291                         "continue after detach; detach anyway? ")))
02292             error (_("Not confirmed."));
02293         }
02294       else
02295         {
02296           if (!query (_("Trace is running but will "
02297                         "stop on detach; detach anyway? ")))
02298             error (_("Not confirmed."));
02299         }
02300     }
02301 }
02302 
02303 /* This function handles the details of what to do about an ongoing
02304    tracing run if the user has asked to detach or otherwise disconnect
02305    from the target.  */
02306 
02307 void
02308 disconnect_tracing (void)
02309 {
02310   /* Also we want to be out of tfind mode, otherwise things can get
02311      confusing upon reconnection.  Just use these calls instead of
02312      full tfind_1 behavior because we're in the middle of detaching,
02313      and there's no point to updating current stack frame etc.  */
02314   trace_reset_local_state ();
02315 }
02316 
02317 /* Worker function for the various flavors of the tfind command.  */
02318 void
02319 tfind_1 (enum trace_find_type type, int num,
02320          CORE_ADDR addr1, CORE_ADDR addr2,
02321          int from_tty)
02322 {
02323   int target_frameno = -1, target_tracept = -1;
02324   struct frame_id old_frame_id = null_frame_id;
02325   struct tracepoint *tp;
02326   struct ui_out *uiout = current_uiout;
02327 
02328   /* Only try to get the current stack frame if we have a chance of
02329      succeeding.  In particular, if we're trying to get a first trace
02330      frame while all threads are running, it's not going to succeed,
02331      so leave it with a default value and let the frame comparison
02332      below (correctly) decide to print out the source location of the
02333      trace frame.  */
02334   if (!(type == tfind_number && num == -1)
02335       && (has_stack_frames () || traceframe_number >= 0))
02336     old_frame_id = get_frame_id (get_current_frame ());
02337 
02338   target_frameno = target_trace_find (type, num, addr1, addr2,
02339                                       &target_tracept);
02340   
02341   if (type == tfind_number
02342       && num == -1
02343       && target_frameno == -1)
02344     {
02345       /* We told the target to get out of tfind mode, and it did.  */
02346     }
02347   else if (target_frameno == -1)
02348     {
02349       /* A request for a non-existent trace frame has failed.
02350          Our response will be different, depending on FROM_TTY:
02351 
02352          If FROM_TTY is true, meaning that this command was 
02353          typed interactively by the user, then give an error
02354          and DO NOT change the state of traceframe_number etc.
02355 
02356          However if FROM_TTY is false, meaning that we're either
02357          in a script, a loop, or a user-defined command, then 
02358          DON'T give an error, but DO change the state of
02359          traceframe_number etc. to invalid.
02360 
02361          The rationalle is that if you typed the command, you
02362          might just have committed a typo or something, and you'd
02363          like to NOT lose your current debugging state.  However
02364          if you're in a user-defined command or especially in a
02365          loop, then you need a way to detect that the command
02366          failed WITHOUT aborting.  This allows you to write
02367          scripts that search thru the trace buffer until the end,
02368          and then continue on to do something else.  */
02369   
02370       if (from_tty)
02371         error (_("Target failed to find requested trace frame."));
02372       else
02373         {
02374           if (info_verbose)
02375             printf_filtered ("End of trace buffer.\n");
02376 #if 0 /* dubious now?  */
02377           /* The following will not recurse, since it's
02378              special-cased.  */
02379           trace_find_command ("-1", from_tty);
02380 #endif
02381         }
02382     }
02383   
02384   tp = get_tracepoint_by_number_on_target (target_tracept);
02385 
02386   reinit_frame_cache ();
02387   target_dcache_invalidate ();
02388 
02389   set_tracepoint_num (tp ? tp->base.number : target_tracept);
02390 
02391   if (target_frameno != get_traceframe_number ())
02392     observer_notify_traceframe_changed (target_frameno, tracepoint_number);
02393 
02394   set_current_traceframe (target_frameno);
02395 
02396   if (target_frameno == -1)
02397     set_traceframe_context (NULL);
02398   else
02399     set_traceframe_context (get_current_frame ());
02400 
02401   if (traceframe_number >= 0)
02402     {
02403       /* Use different branches for MI and CLI to make CLI messages
02404          i18n-eable.  */
02405       if (ui_out_is_mi_like_p (uiout))
02406         {
02407           ui_out_field_string (uiout, "found", "1");
02408           ui_out_field_int (uiout, "tracepoint", tracepoint_number);
02409           ui_out_field_int (uiout, "traceframe", traceframe_number);
02410         }
02411       else
02412         {
02413           printf_unfiltered (_("Found trace frame %d, tracepoint %d\n"),
02414                              traceframe_number, tracepoint_number);
02415         }
02416     }
02417   else
02418     {
02419       if (ui_out_is_mi_like_p (uiout))
02420         ui_out_field_string (uiout, "found", "0");
02421       else if (type == tfind_number && num == -1)
02422         printf_unfiltered (_("No longer looking at any trace frame\n"));
02423       else /* This case may never occur, check.  */
02424         printf_unfiltered (_("No trace frame found\n"));
02425     }
02426 
02427   /* If we're in nonstop mode and getting out of looking at trace
02428      frames, there won't be any current frame to go back to and
02429      display.  */
02430   if (from_tty
02431       && (has_stack_frames () || traceframe_number >= 0))
02432     {
02433       enum print_what print_what;
02434 
02435       /* NOTE: in imitation of the step command, try to determine
02436          whether we have made a transition from one function to
02437          another.  If so, we'll print the "stack frame" (ie. the new
02438          function and it's arguments) -- otherwise we'll just show the
02439          new source line.  */
02440 
02441       if (frame_id_eq (old_frame_id,
02442                        get_frame_id (get_current_frame ())))
02443         print_what = SRC_LINE;
02444       else
02445         print_what = SRC_AND_LOC;
02446 
02447       print_stack_frame (get_selected_frame (NULL), 1, print_what, 1);
02448       do_displays ();
02449     }
02450 }
02451 
02452 /* trace_find_command takes a trace frame number n, 
02453    sends "QTFrame:<n>" to the target, 
02454    and accepts a reply that may contain several optional pieces
02455    of information: a frame number, a tracepoint number, and an
02456    indication of whether this is a trap frame or a stepping frame.
02457 
02458    The minimal response is just "OK" (which indicates that the 
02459    target does not give us a frame number or a tracepoint number).
02460    Instead of that, the target may send us a string containing
02461    any combination of:
02462    F<hexnum>    (gives the selected frame number)
02463    T<hexnum>    (gives the selected tracepoint number)
02464  */
02465 
02466 /* tfind command */
02467 static void
02468 trace_find_command (char *args, int from_tty)
02469 { /* This should only be called with a numeric argument.  */
02470   int frameno = -1;
02471 
02472   if (current_trace_status ()->running
02473       && current_trace_status ()->filename == NULL)
02474     error (_("May not look at trace frames while trace is running."));
02475   
02476   if (args == 0 || *args == 0)
02477     { /* TFIND with no args means find NEXT trace frame.  */
02478       if (traceframe_number == -1)
02479         frameno = 0;    /* "next" is first one.  */
02480         else
02481         frameno = traceframe_number + 1;
02482     }
02483   else if (0 == strcmp (args, "-"))
02484     {
02485       if (traceframe_number == -1)
02486         error (_("not debugging trace buffer"));
02487       else if (from_tty && traceframe_number == 0)
02488         error (_("already at start of trace buffer"));
02489       
02490       frameno = traceframe_number - 1;
02491       }
02492   /* A hack to work around eval's need for fp to have been collected.  */
02493   else if (0 == strcmp (args, "-1"))
02494     frameno = -1;
02495   else
02496     frameno = parse_and_eval_long (args);
02497 
02498   if (frameno < -1)
02499     error (_("invalid input (%d is less than zero)"), frameno);
02500 
02501   tfind_1 (tfind_number, frameno, 0, 0, from_tty);
02502 }
02503 
02504 /* tfind end */
02505 static void
02506 trace_find_end_command (char *args, int from_tty)
02507 {
02508   trace_find_command ("-1", from_tty);
02509 }
02510 
02511 /* tfind start */
02512 static void
02513 trace_find_start_command (char *args, int from_tty)
02514 {
02515   trace_find_command ("0", from_tty);
02516 }
02517 
02518 /* tfind pc command */
02519 static void
02520 trace_find_pc_command (char *args, int from_tty)
02521 {
02522   CORE_ADDR pc;
02523 
02524   if (current_trace_status ()->running
02525       && current_trace_status ()->filename == NULL)
02526     error (_("May not look at trace frames while trace is running."));
02527 
02528   if (args == 0 || *args == 0)
02529     pc = regcache_read_pc (get_current_regcache ());
02530   else
02531     pc = parse_and_eval_address (args);
02532 
02533   tfind_1 (tfind_pc, 0, pc, 0, from_tty);
02534 }
02535 
02536 /* tfind tracepoint command */
02537 static void
02538 trace_find_tracepoint_command (char *args, int from_tty)
02539 {
02540   int tdp;
02541   struct tracepoint *tp;
02542 
02543   if (current_trace_status ()->running
02544       && current_trace_status ()->filename == NULL)
02545     error (_("May not look at trace frames while trace is running."));
02546 
02547   if (args == 0 || *args == 0)
02548     {
02549       if (tracepoint_number == -1)
02550         error (_("No current tracepoint -- please supply an argument."));
02551       else
02552         tdp = tracepoint_number;        /* Default is current TDP.  */
02553     }
02554   else
02555     tdp = parse_and_eval_long (args);
02556 
02557   /* If we have the tracepoint on hand, use the number that the
02558      target knows about (which may be different if we disconnected
02559      and reconnected).  */
02560   tp = get_tracepoint (tdp);
02561   if (tp)
02562     tdp = tp->number_on_target;
02563 
02564   tfind_1 (tfind_tp, tdp, 0, 0, from_tty);
02565 }
02566 
02567 /* TFIND LINE command:
02568 
02569    This command will take a sourceline for argument, just like BREAK
02570    or TRACE (ie. anything that "decode_line_1" can handle).
02571 
02572    With no argument, this command will find the next trace frame 
02573    corresponding to a source line OTHER THAN THE CURRENT ONE.  */
02574 
02575 static void
02576 trace_find_line_command (char *args, int from_tty)
02577 {
02578   static CORE_ADDR start_pc, end_pc;
02579   struct symtabs_and_lines sals;
02580   struct symtab_and_line sal;
02581   struct cleanup *old_chain;
02582 
02583   if (current_trace_status ()->running
02584       && current_trace_status ()->filename == NULL)
02585     error (_("May not look at trace frames while trace is running."));
02586 
02587   if (args == 0 || *args == 0)
02588     {
02589       sal = find_pc_line (get_frame_pc (get_current_frame ()), 0);
02590       sals.nelts = 1;
02591       sals.sals = (struct symtab_and_line *)
02592         xmalloc (sizeof (struct symtab_and_line));
02593       sals.sals[0] = sal;
02594     }
02595   else
02596     {
02597       sals = decode_line_with_current_source (args, DECODE_LINE_FUNFIRSTLINE);
02598       sal = sals.sals[0];
02599     }
02600   
02601   old_chain = make_cleanup (xfree, sals.sals);
02602   if (sal.symtab == 0)
02603     error (_("No line number information available."));
02604 
02605   if (sal.line > 0 && find_line_pc_range (sal, &start_pc, &end_pc))
02606     {
02607       if (start_pc == end_pc)
02608         {
02609           printf_filtered ("Line %d of \"%s\"",
02610                            sal.line,
02611                            symtab_to_filename_for_display (sal.symtab));
02612           wrap_here ("  ");
02613           printf_filtered (" is at address ");
02614           print_address (get_current_arch (), start_pc, gdb_stdout);
02615           wrap_here ("  ");
02616           printf_filtered (" but contains no code.\n");
02617           sal = find_pc_line (start_pc, 0);
02618           if (sal.line > 0
02619               && find_line_pc_range (sal, &start_pc, &end_pc)
02620               && start_pc != end_pc)
02621             printf_filtered ("Attempting to find line %d instead.\n",
02622                              sal.line);
02623           else
02624             error (_("Cannot find a good line."));
02625         }
02626       }
02627     else
02628     /* Is there any case in which we get here, and have an address
02629        which the user would want to see?  If we have debugging
02630        symbols and no line numbers?  */
02631     error (_("Line number %d is out of range for \"%s\"."),
02632            sal.line, symtab_to_filename_for_display (sal.symtab));
02633 
02634   /* Find within range of stated line.  */
02635   if (args && *args)
02636     tfind_1 (tfind_range, 0, start_pc, end_pc - 1, from_tty);
02637   else
02638     tfind_1 (tfind_outside, 0, start_pc, end_pc - 1, from_tty);
02639   do_cleanups (old_chain);
02640 }
02641 
02642 /* tfind range command */
02643 static void
02644 trace_find_range_command (char *args, int from_tty)
02645 {
02646   static CORE_ADDR start, stop;
02647   char *tmp;
02648 
02649   if (current_trace_status ()->running
02650       && current_trace_status ()->filename == NULL)
02651     error (_("May not look at trace frames while trace is running."));
02652 
02653   if (args == 0 || *args == 0)
02654     { /* XXX FIXME: what should default behavior be?  */
02655       printf_filtered ("Usage: tfind range <startaddr>,<endaddr>\n");
02656       return;
02657     }
02658 
02659   if (0 != (tmp = strchr (args, ',')))
02660     {
02661       *tmp++ = '\0';    /* Terminate start address.  */
02662       tmp = skip_spaces (tmp);
02663       start = parse_and_eval_address (args);
02664       stop = parse_and_eval_address (tmp);
02665     }
02666   else
02667     {                   /* No explicit end address?  */
02668       start = parse_and_eval_address (args);
02669       stop = start + 1; /* ??? */
02670     }
02671 
02672   tfind_1 (tfind_range, 0, start, stop, from_tty);
02673 }
02674 
02675 /* tfind outside command */
02676 static void
02677 trace_find_outside_command (char *args, int from_tty)
02678 {
02679   CORE_ADDR start, stop;
02680   char *tmp;
02681 
02682   if (current_trace_status ()->running
02683       && current_trace_status ()->filename == NULL)
02684     error (_("May not look at trace frames while trace is running."));
02685 
02686   if (args == 0 || *args == 0)
02687     { /* XXX FIXME: what should default behavior be?  */
02688       printf_filtered ("Usage: tfind outside <startaddr>,<endaddr>\n");
02689       return;
02690     }
02691 
02692   if (0 != (tmp = strchr (args, ',')))
02693     {
02694       *tmp++ = '\0';    /* Terminate start address.  */
02695       tmp = skip_spaces (tmp);
02696       start = parse_and_eval_address (args);
02697       stop = parse_and_eval_address (tmp);
02698     }
02699   else
02700     {                   /* No explicit end address?  */
02701       start = parse_and_eval_address (args);
02702       stop = start + 1; /* ??? */
02703     }
02704 
02705   tfind_1 (tfind_outside, 0, start, stop, from_tty);
02706 }
02707 
02708 /* info scope command: list the locals for a scope.  */
02709 static void
02710 scope_info (char *args, int from_tty)
02711 {
02712   struct symtabs_and_lines sals;
02713   struct symbol *sym;
02714   struct minimal_symbol *msym;
02715   struct block *block;
02716   const char *symname;
02717   char *save_args = args;
02718   struct block_iterator iter;
02719   int j, count = 0;
02720   struct gdbarch *gdbarch;
02721   int regno;
02722 
02723   if (args == 0 || *args == 0)
02724     error (_("requires an argument (function, "
02725              "line or *addr) to define a scope"));
02726 
02727   sals = decode_line_1 (&args, DECODE_LINE_FUNFIRSTLINE, NULL, 0);
02728   if (sals.nelts == 0)
02729     return;             /* Presumably decode_line_1 has already warned.  */
02730 
02731   /* Resolve line numbers to PC.  */
02732   resolve_sal_pc (&sals.sals[0]);
02733   block = block_for_pc (sals.sals[0].pc);
02734 
02735   while (block != 0)
02736     {
02737       QUIT;                     /* Allow user to bail out with ^C.  */
02738       ALL_BLOCK_SYMBOLS (block, iter, sym)
02739         {
02740           QUIT;                 /* Allow user to bail out with ^C.  */
02741           if (count == 0)
02742             printf_filtered ("Scope for %s:\n", save_args);
02743           count++;
02744 
02745           symname = SYMBOL_PRINT_NAME (sym);
02746           if (symname == NULL || *symname == '\0')
02747             continue;           /* Probably botched, certainly useless.  */
02748 
02749           gdbarch = get_objfile_arch (SYMBOL_SYMTAB (sym)->objfile);
02750 
02751           printf_filtered ("Symbol %s is ", symname);
02752 
02753           if (SYMBOL_COMPUTED_OPS (sym) != NULL)
02754             SYMBOL_COMPUTED_OPS (sym)->describe_location (sym,
02755                                                           BLOCK_START (block),
02756                                                           gdb_stdout);
02757           else
02758             {
02759               switch (SYMBOL_CLASS (sym))
02760                 {
02761                 default:
02762                 case LOC_UNDEF: /* Messed up symbol?  */
02763                   printf_filtered ("a bogus symbol, class %d.\n",
02764                                    SYMBOL_CLASS (sym));
02765                   count--;              /* Don't count this one.  */
02766                   continue;
02767                 case LOC_CONST:
02768                   printf_filtered ("a constant with value %s (%s)",
02769                                    plongest (SYMBOL_VALUE (sym)),
02770                                    hex_string (SYMBOL_VALUE (sym)));
02771                   break;
02772                 case LOC_CONST_BYTES:
02773                   printf_filtered ("constant bytes: ");
02774                   if (SYMBOL_TYPE (sym))
02775                     for (j = 0; j < TYPE_LENGTH (SYMBOL_TYPE (sym)); j++)
02776                       fprintf_filtered (gdb_stdout, " %02x",
02777                                         (unsigned) SYMBOL_VALUE_BYTES (sym)[j]);
02778                   break;
02779                 case LOC_STATIC:
02780                   printf_filtered ("in static storage at address ");
02781                   printf_filtered ("%s", paddress (gdbarch,
02782                                                    SYMBOL_VALUE_ADDRESS (sym)));
02783                   break;
02784                 case LOC_REGISTER:
02785                   /* GDBARCH is the architecture associated with the objfile
02786                      the symbol is defined in; the target architecture may be
02787                      different, and may provide additional registers.  However,
02788                      we do not know the target architecture at this point.
02789                      We assume the objfile architecture will contain all the
02790                      standard registers that occur in debug info in that
02791                      objfile.  */
02792                   regno = SYMBOL_REGISTER_OPS (sym)->register_number (sym,
02793                                                                       gdbarch);
02794 
02795                   if (SYMBOL_IS_ARGUMENT (sym))
02796                     printf_filtered ("an argument in register $%s",
02797                                      gdbarch_register_name (gdbarch, regno));
02798                   else
02799                     printf_filtered ("a local variable in register $%s",
02800                                      gdbarch_register_name (gdbarch, regno));
02801                   break;
02802                 case LOC_ARG:
02803                   printf_filtered ("an argument at stack/frame offset %s",
02804                                    plongest (SYMBOL_VALUE (sym)));
02805                   break;
02806                 case LOC_LOCAL:
02807                   printf_filtered ("a local variable at frame offset %s",
02808                                    plongest (SYMBOL_VALUE (sym)));
02809                   break;
02810                 case LOC_REF_ARG:
02811                   printf_filtered ("a reference argument at offset %s",
02812                                    plongest (SYMBOL_VALUE (sym)));
02813                   break;
02814                 case LOC_REGPARM_ADDR:
02815                   /* Note comment at LOC_REGISTER.  */
02816                   regno = SYMBOL_REGISTER_OPS (sym)->register_number (sym,
02817                                                                       gdbarch);
02818                   printf_filtered ("the address of an argument, in register $%s",
02819                                    gdbarch_register_name (gdbarch, regno));
02820                   break;
02821                 case LOC_TYPEDEF:
02822                   printf_filtered ("a typedef.\n");
02823                   continue;
02824                 case LOC_LABEL:
02825                   printf_filtered ("a label at address ");
02826                   printf_filtered ("%s", paddress (gdbarch,
02827                                                    SYMBOL_VALUE_ADDRESS (sym)));
02828                   break;
02829                 case LOC_BLOCK:
02830                   printf_filtered ("a function at address ");
02831                   printf_filtered ("%s",
02832                                    paddress (gdbarch, BLOCK_START (SYMBOL_BLOCK_VALUE (sym))));
02833                   break;
02834                 case LOC_UNRESOLVED:
02835                   msym = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (sym),
02836                                                 NULL, NULL);
02837                   if (msym == NULL)
02838                     printf_filtered ("Unresolved Static");
02839                   else
02840                     {
02841                       printf_filtered ("static storage at address ");
02842                       printf_filtered ("%s",
02843                                        paddress (gdbarch,
02844                                                  SYMBOL_VALUE_ADDRESS (msym)));
02845                     }
02846                   break;
02847                 case LOC_OPTIMIZED_OUT:
02848                   printf_filtered ("optimized out.\n");
02849                   continue;
02850                 case LOC_COMPUTED:
02851                   gdb_assert_not_reached (_("LOC_COMPUTED variable missing a method"));
02852                 }
02853             }
02854           if (SYMBOL_TYPE (sym))
02855             printf_filtered (", length %d.\n",
02856                              TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym))));
02857         }
02858       if (BLOCK_FUNCTION (block))
02859         break;
02860       else
02861         block = BLOCK_SUPERBLOCK (block);
02862     }
02863   if (count <= 0)
02864     printf_filtered ("Scope for %s contains no locals or arguments.\n",
02865                      save_args);
02866 }
02867 
02868 /* Helper for trace_dump_command.  Dump the action list starting at
02869    ACTION.  STEPPING_ACTIONS is true if we're iterating over the
02870    actions of the body of a while-stepping action.  STEPPING_FRAME is
02871    set if the current traceframe was determined to be a while-stepping
02872    traceframe.  */
02873 
02874 static void
02875 trace_dump_actions (struct command_line *action,
02876                     int stepping_actions, int stepping_frame,
02877                     int from_tty)
02878 {
02879   const char *action_exp, *next_comma;
02880 
02881   for (; action != NULL; action = action->next)
02882     {
02883       struct cmd_list_element *cmd;
02884 
02885       QUIT;                     /* Allow user to bail out with ^C.  */
02886       action_exp = action->line;
02887       action_exp = skip_spaces_const (action_exp);
02888 
02889       /* The collection actions to be done while stepping are
02890          bracketed by the commands "while-stepping" and "end".  */
02891 
02892       if (*action_exp == '#')   /* comment line */
02893         continue;
02894 
02895       cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
02896       if (cmd == 0)
02897         error (_("Bad action list item: %s"), action_exp);
02898 
02899       if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand))
02900         {
02901           int i;
02902 
02903           for (i = 0; i < action->body_count; ++i)
02904             trace_dump_actions (action->body_list[i],
02905                                 1, stepping_frame, from_tty);
02906         }
02907       else if (cmd_cfunc_eq (cmd, collect_pseudocommand))
02908         {
02909           /* Display the collected data.
02910              For the trap frame, display only what was collected at
02911              the trap.  Likewise for stepping frames, display only
02912              what was collected while stepping.  This means that the
02913              two boolean variables, STEPPING_FRAME and
02914              STEPPING_ACTIONS should be equal.  */
02915           if (stepping_frame == stepping_actions)
02916             {
02917               char *cmd = NULL;
02918               struct cleanup *old_chain
02919                 = make_cleanup (free_current_contents, &cmd);
02920               int trace_string = 0;
02921 
02922               if (*action_exp == '/')
02923                 action_exp = decode_agent_options (action_exp, &trace_string);
02924 
02925               do
02926                 {               /* Repeat over a comma-separated list.  */
02927                   QUIT;         /* Allow user to bail out with ^C.  */
02928                   if (*action_exp == ',')
02929                     action_exp++;
02930                   action_exp = skip_spaces_const (action_exp);
02931 
02932                   next_comma = strchr (action_exp, ',');
02933 
02934                   if (0 == strncasecmp (action_exp, "$reg", 4))
02935                     registers_info (NULL, from_tty);
02936                   else if (0 == strncasecmp (action_exp, "$_ret", 5))
02937                     ;
02938                   else if (0 == strncasecmp (action_exp, "$loc", 4))
02939                     locals_info (NULL, from_tty);
02940                   else if (0 == strncasecmp (action_exp, "$arg", 4))
02941                     args_info (NULL, from_tty);
02942                   else
02943                     {           /* variable */
02944                       if (next_comma != NULL)
02945                         {
02946                           size_t len = next_comma - action_exp;
02947 
02948                           cmd = xrealloc (cmd, len + 1);
02949                           memcpy (cmd, action_exp, len);
02950                           cmd[len] = 0;
02951                         }
02952                       else
02953                         {
02954                           size_t len = strlen (action_exp);
02955 
02956                           cmd = xrealloc (cmd, len + 1);
02957                           memcpy (cmd, action_exp, len + 1);
02958                         }
02959 
02960                       printf_filtered ("%s = ", cmd);
02961                       output_command_const (cmd, from_tty);
02962                       printf_filtered ("\n");
02963                     }
02964                   action_exp = next_comma;
02965                 }
02966               while (action_exp && *action_exp == ',');
02967 
02968               do_cleanups (old_chain);
02969             }
02970         }
02971     }
02972 }
02973 
02974 /* Return bp_location of the tracepoint associated with the current
02975    traceframe.  Set *STEPPING_FRAME_P to 1 if the current traceframe
02976    is a stepping traceframe.  */
02977 
02978 struct bp_location *
02979 get_traceframe_location (int *stepping_frame_p)
02980 {
02981   struct tracepoint *t;
02982   struct bp_location *tloc;
02983   struct regcache *regcache;
02984 
02985   if (tracepoint_number == -1)
02986     error (_("No current trace frame."));
02987 
02988   t = get_tracepoint (tracepoint_number);
02989 
02990   if (t == NULL)
02991     error (_("No known tracepoint matches 'current' tracepoint #%d."),
02992            tracepoint_number);
02993 
02994   /* The current frame is a trap frame if the frame PC is equal to the
02995      tracepoint PC.  If not, then the current frame was collected
02996      during single-stepping.  */
02997   regcache = get_current_regcache ();
02998 
02999   /* If the traceframe's address matches any of the tracepoint's
03000      locations, assume it is a direct hit rather than a while-stepping
03001      frame.  (FIXME this is not reliable, should record each frame's
03002      type.)  */
03003   for (tloc = t->base.loc; tloc; tloc = tloc->next)
03004     if (tloc->address == regcache_read_pc (regcache))
03005       {
03006         *stepping_frame_p = 0;
03007         return tloc;
03008       }
03009 
03010   /* If this is a stepping frame, we don't know which location
03011      triggered.  The first is as good (or bad) a guess as any...  */
03012   *stepping_frame_p = 1;
03013   return t->base.loc;
03014 }
03015 
03016 /* Return all the actions, including default collect, of a tracepoint
03017    T.  It constructs cleanups into the chain, and leaves the caller to
03018    handle them (call do_cleanups).  */
03019 
03020 static struct command_line *
03021 all_tracepoint_actions_and_cleanup (struct breakpoint *t)
03022 {
03023   struct command_line *actions;
03024 
03025   actions = breakpoint_commands (t);
03026 
03027   /* If there are default expressions to collect, make up a collect
03028      action and prepend to the action list to encode.  Note that since
03029      validation is per-tracepoint (local var "xyz" might be valid for
03030      one tracepoint and not another, etc), we make up the action on
03031      the fly, and don't cache it.  */
03032   if (*default_collect)
03033     {
03034       struct command_line *default_collect_action;
03035       char *default_collect_line;
03036 
03037       default_collect_line = xstrprintf ("collect %s", default_collect);
03038       make_cleanup (xfree, default_collect_line);
03039 
03040       validate_actionline (default_collect_line, t);
03041       default_collect_action = xmalloc (sizeof (struct command_line));
03042       make_cleanup (xfree, default_collect_action);
03043       default_collect_action->next = actions;
03044       default_collect_action->line = default_collect_line;
03045       actions = default_collect_action;
03046     }
03047 
03048   return actions;
03049 }
03050 
03051 /* The tdump command.  */
03052 
03053 static void
03054 trace_dump_command (char *args, int from_tty)
03055 {
03056   int stepping_frame = 0;
03057   struct bp_location *loc;
03058   struct cleanup *old_chain;
03059   struct command_line *actions;
03060 
03061   /* This throws an error is not inspecting a trace frame.  */
03062   loc = get_traceframe_location (&stepping_frame);
03063 
03064   printf_filtered ("Data collected at tracepoint %d, trace frame %d:\n",
03065                    tracepoint_number, traceframe_number);
03066 
03067   old_chain = make_cleanup (null_cleanup, NULL);
03068 
03069   /* This command only makes sense for the current frame, not the
03070      selected frame.  */
03071   make_cleanup_restore_current_thread ();
03072   select_frame (get_current_frame ());
03073 
03074   actions = all_tracepoint_actions_and_cleanup (loc->owner);
03075 
03076   trace_dump_actions (actions, 0, stepping_frame, from_tty);
03077 
03078   do_cleanups (old_chain);
03079 }
03080 
03081 /* Encode a piece of a tracepoint's source-level definition in a form
03082    that is suitable for both protocol and saving in files.  */
03083 /* This version does not do multiple encodes for long strings; it should
03084    return an offset to the next piece to encode.  FIXME  */
03085 
03086 extern int
03087 encode_source_string (int tpnum, ULONGEST addr,
03088                       char *srctype, char *src, char *buf, int buf_size)
03089 {
03090   if (80 + strlen (srctype) > buf_size)
03091     error (_("Buffer too small for source encoding"));
03092   sprintf (buf, "%x:%s:%s:%x:%x:",
03093            tpnum, phex_nz (addr, sizeof (addr)),
03094            srctype, 0, (int) strlen (src));
03095   if (strlen (buf) + strlen (src) * 2 >= buf_size)
03096     error (_("Source string too long for buffer"));
03097   bin2hex ((gdb_byte *) src, buf + strlen (buf), 0);
03098   return -1;
03099 }
03100 
03101 /* Free trace file writer.  */
03102 
03103 static void
03104 trace_file_writer_xfree (void *arg)
03105 {
03106   struct trace_file_writer *writer = arg;
03107 
03108   writer->ops->dtor (writer);
03109   xfree (writer);
03110 }
03111 
03112 /* TFILE trace writer.  */
03113 
03114 struct tfile_trace_file_writer
03115 {
03116   struct trace_file_writer base;
03117 
03118   /* File pointer to tfile trace file.  */
03119   FILE *fp;
03120   /* Path name of the tfile trace file.  */
03121   char *pathname;
03122 };
03123 
03124 /* This is the implementation of trace_file_write_ops method
03125    target_save.  We just call the generic target
03126    target_save_trace_data to do target-side saving.  */
03127 
03128 static int
03129 tfile_target_save (struct trace_file_writer *self,
03130                    const char *filename)
03131 {
03132   int err = target_save_trace_data (filename);
03133 
03134   return (err >= 0);
03135 }
03136 
03137 /* This is the implementation of trace_file_write_ops method
03138    dtor.  */
03139 
03140 static void
03141 tfile_dtor (struct trace_file_writer *self)
03142 {
03143   struct tfile_trace_file_writer *writer
03144     = (struct tfile_trace_file_writer *) self;
03145 
03146   xfree (writer->pathname);
03147 
03148   if (writer->fp != NULL)
03149     fclose (writer->fp);
03150 }
03151 
03152 /* This is the implementation of trace_file_write_ops method
03153    start.  It creates the trace file FILENAME and registers some
03154    cleanups.  */
03155 
03156 static void
03157 tfile_start (struct trace_file_writer *self, const char *filename)
03158 {
03159   struct tfile_trace_file_writer *writer
03160     = (struct tfile_trace_file_writer *) self;
03161 
03162   writer->pathname = tilde_expand (filename);
03163   writer->fp = gdb_fopen_cloexec (writer->pathname, "wb");
03164   if (writer->fp == NULL)
03165     error (_("Unable to open file '%s' for saving trace data (%s)"),
03166            writer->pathname, safe_strerror (errno));
03167 }
03168 
03169 /* This is the implementation of trace_file_write_ops method
03170    write_header.  Write the TFILE header.  */
03171 
03172 static void
03173 tfile_write_header (struct trace_file_writer *self)
03174 {
03175   struct tfile_trace_file_writer *writer
03176     = (struct tfile_trace_file_writer *) self;
03177   int written;
03178 
03179   /* Write a file header, with a high-bit-set char to indicate a
03180      binary file, plus a hint as what this file is, and a version
03181      number in case of future needs.  */
03182   written = fwrite ("\x7fTRACE0\n", 8, 1, writer->fp);
03183   if (written < 1)
03184     perror_with_name (writer->pathname);
03185 }
03186 
03187 /* This is the implementation of trace_file_write_ops method
03188    write_regblock_type.  Write the size of register block.  */
03189 
03190 static void
03191 tfile_write_regblock_type (struct trace_file_writer *self, int size)
03192 {
03193   struct tfile_trace_file_writer *writer
03194     = (struct tfile_trace_file_writer *) self;
03195 
03196   fprintf (writer->fp, "R %x\n", size);
03197 }
03198 
03199 /* This is the implementation of trace_file_write_ops method
03200    write_status.  */
03201 
03202 static void
03203 tfile_write_status (struct trace_file_writer *self,
03204                     struct trace_status *ts)
03205 {
03206   struct tfile_trace_file_writer *writer
03207     = (struct tfile_trace_file_writer *) self;
03208 
03209   fprintf (writer->fp, "status %c;%s",
03210            (ts->running ? '1' : '0'), stop_reason_names[ts->stop_reason]);
03211   if (ts->stop_reason == tracepoint_error
03212       || ts->stop_reason == tstop_command)
03213     {
03214       char *buf = (char *) alloca (strlen (ts->stop_desc) * 2 + 1);
03215 
03216       bin2hex ((gdb_byte *) ts->stop_desc, buf, 0);
03217       fprintf (writer->fp, ":%s", buf);
03218     }
03219   fprintf (writer->fp, ":%x", ts->stopping_tracepoint);
03220   if (ts->traceframe_count >= 0)
03221     fprintf (writer->fp, ";tframes:%x", ts->traceframe_count);
03222   if (ts->traceframes_created >= 0)
03223     fprintf (writer->fp, ";tcreated:%x", ts->traceframes_created);
03224   if (ts->buffer_free >= 0)
03225     fprintf (writer->fp, ";tfree:%x", ts->buffer_free);
03226   if (ts->buffer_size >= 0)
03227     fprintf (writer->fp, ";tsize:%x", ts->buffer_size);
03228   if (ts->disconnected_tracing)
03229     fprintf (writer->fp, ";disconn:%x", ts->disconnected_tracing);
03230   if (ts->circular_buffer)
03231     fprintf (writer->fp, ";circular:%x", ts->circular_buffer);
03232   if (ts->start_time)
03233     {
03234       fprintf (writer->fp, ";starttime:%s",
03235       phex_nz (ts->start_time, sizeof (ts->start_time)));
03236     }
03237   if (ts->stop_time)
03238     {
03239       fprintf (writer->fp, ";stoptime:%s",
03240       phex_nz (ts->stop_time, sizeof (ts->stop_time)));
03241     }
03242   if (ts->notes != NULL)
03243     {
03244       char *buf = (char *) alloca (strlen (ts->notes) * 2 + 1);
03245 
03246       bin2hex ((gdb_byte *) ts->notes, buf, 0);
03247       fprintf (writer->fp, ";notes:%s", buf);
03248     }
03249   if (ts->user_name != NULL)
03250     {
03251       char *buf = (char *) alloca (strlen (ts->user_name) * 2 + 1);
03252 
03253       bin2hex ((gdb_byte *) ts->user_name, buf, 0);
03254       fprintf (writer->fp, ";username:%s", buf);
03255     }
03256   fprintf (writer->fp, "\n");
03257 }
03258 
03259 /* This is the implementation of trace_file_write_ops method
03260    write_uploaded_tsv.  */
03261 
03262 static void
03263 tfile_write_uploaded_tsv (struct trace_file_writer *self,
03264                           struct uploaded_tsv *utsv)
03265 {
03266   char *buf = "";
03267   struct tfile_trace_file_writer *writer
03268     = (struct tfile_trace_file_writer *) self;
03269 
03270   if (utsv->name)
03271     {
03272       buf = (char *) xmalloc (strlen (utsv->name) * 2 + 1);
03273       bin2hex ((gdb_byte *) (utsv->name), buf, 0);
03274     }
03275 
03276   fprintf (writer->fp, "tsv %x:%s:%x:%s\n",
03277            utsv->number, phex_nz (utsv->initial_value, 8),
03278            utsv->builtin, buf);
03279 
03280   if (utsv->name)
03281     xfree (buf);
03282 }
03283 
03284 #define MAX_TRACE_UPLOAD 2000
03285 
03286 /* This is the implementation of trace_file_write_ops method
03287    write_uploaded_tp.  */
03288 
03289 static void
03290 tfile_write_uploaded_tp (struct trace_file_writer *self,
03291                          struct uploaded_tp *utp)
03292 {
03293   struct tfile_trace_file_writer *writer
03294     = (struct tfile_trace_file_writer *) self;
03295   int a;
03296   char *act;
03297   char buf[MAX_TRACE_UPLOAD];
03298 
03299   fprintf (writer->fp, "tp T%x:%s:%c:%x:%x",
03300            utp->number, phex_nz (utp->addr, sizeof (utp->addr)),
03301            (utp->enabled ? 'E' : 'D'), utp->step, utp->pass);
03302   if (utp->type == bp_fast_tracepoint)
03303     fprintf (writer->fp, ":F%x", utp->orig_size);
03304   if (utp->cond)
03305     fprintf (writer->fp,
03306              ":X%x,%s", (unsigned int) strlen (utp->cond) / 2,
03307              utp->cond);
03308   fprintf (writer->fp, "\n");
03309   for (a = 0; VEC_iterate (char_ptr, utp->actions, a, act); ++a)
03310     fprintf (writer->fp, "tp A%x:%s:%s\n",
03311              utp->number, phex_nz (utp->addr, sizeof (utp->addr)), act);
03312   for (a = 0; VEC_iterate (char_ptr, utp->step_actions, a, act); ++a)
03313     fprintf (writer->fp, "tp S%x:%s:%s\n",
03314              utp->number, phex_nz (utp->addr, sizeof (utp->addr)), act);
03315   if (utp->at_string)
03316     {
03317       encode_source_string (utp->number, utp->addr,
03318                             "at", utp->at_string, buf, MAX_TRACE_UPLOAD);
03319       fprintf (writer->fp, "tp Z%s\n", buf);
03320     }
03321   if (utp->cond_string)
03322     {
03323       encode_source_string (utp->number, utp->addr,
03324                             "cond", utp->cond_string,
03325                             buf, MAX_TRACE_UPLOAD);
03326       fprintf (writer->fp, "tp Z%s\n", buf);
03327     }
03328   for (a = 0; VEC_iterate (char_ptr, utp->cmd_strings, a, act); ++a)
03329     {
03330       encode_source_string (utp->number, utp->addr, "cmd", act,
03331                             buf, MAX_TRACE_UPLOAD);
03332       fprintf (writer->fp, "tp Z%s\n", buf);
03333     }
03334   fprintf (writer->fp, "tp V%x:%s:%x:%s\n",
03335            utp->number, phex_nz (utp->addr, sizeof (utp->addr)),
03336            utp->hit_count,
03337            phex_nz (utp->traceframe_usage,
03338                     sizeof (utp->traceframe_usage)));
03339 }
03340 
03341 /* This is the implementation of trace_file_write_ops method
03342    write_definition_end.  */
03343 
03344 static void
03345 tfile_write_definition_end (struct trace_file_writer *self)
03346 {
03347   struct tfile_trace_file_writer *writer
03348     = (struct tfile_trace_file_writer *) self;
03349 
03350   fprintf (writer->fp, "\n");
03351 }
03352 
03353 /* This is the implementation of trace_file_write_ops method
03354    write_raw_data.  */
03355 
03356 static void
03357 tfile_write_raw_data (struct trace_file_writer *self, gdb_byte *buf,
03358                       LONGEST len)
03359 {
03360   struct tfile_trace_file_writer *writer
03361     = (struct tfile_trace_file_writer *) self;
03362 
03363   if (fwrite (buf, len, 1, writer->fp) < 1)
03364     perror_with_name (writer->pathname);
03365 }
03366 
03367 /* This is the implementation of trace_file_write_ops method
03368    end.  */
03369 
03370 static void
03371 tfile_end (struct trace_file_writer *self)
03372 {
03373   struct tfile_trace_file_writer *writer
03374     = (struct tfile_trace_file_writer *) self;
03375   uint32_t gotten = 0;
03376 
03377   /* Mark the end of trace data.  */
03378   if (fwrite (&gotten, 4, 1, writer->fp) < 1)
03379     perror_with_name (writer->pathname);
03380 }
03381 
03382 /* Operations to write trace buffers into TFILE format.  */
03383 
03384 static const struct trace_file_write_ops tfile_write_ops =
03385 {
03386   tfile_dtor,
03387   tfile_target_save,
03388   tfile_start,
03389   tfile_write_header,
03390   tfile_write_regblock_type,
03391   tfile_write_status,
03392   tfile_write_uploaded_tsv,
03393   tfile_write_uploaded_tp,
03394   tfile_write_definition_end,
03395   tfile_write_raw_data,
03396   NULL,
03397   tfile_end,
03398 };
03399 
03400 /* Helper macros.  */
03401 
03402 #define TRACE_WRITE_R_BLOCK(writer, buf, size)  \
03403   writer->ops->frame_ops->write_r_block ((writer), (buf), (size))
03404 #define TRACE_WRITE_M_BLOCK_HEADER(writer, addr, size)            \
03405   writer->ops->frame_ops->write_m_block_header ((writer), (addr), \
03406                                                 (size))
03407 #define TRACE_WRITE_M_BLOCK_MEMORY(writer, buf, size)     \
03408   writer->ops->frame_ops->write_m_block_memory ((writer), (buf), \
03409                                                 (size))
03410 #define TRACE_WRITE_V_BLOCK(writer, num, val)   \
03411   writer->ops->frame_ops->write_v_block ((writer), (num), (val))
03412 
03413 /* Save tracepoint data to file named FILENAME through WRITER.  WRITER
03414    determines the trace file format.  If TARGET_DOES_SAVE is non-zero,
03415    the save is performed on the target, otherwise GDB obtains all trace
03416    data and saves it locally.  */
03417 
03418 static void
03419 trace_save (const char *filename, struct trace_file_writer *writer,
03420             int target_does_save)
03421 {
03422   struct trace_status *ts = current_trace_status ();
03423   int status;
03424   struct uploaded_tp *uploaded_tps = NULL, *utp;
03425   struct uploaded_tsv *uploaded_tsvs = NULL, *utsv;
03426 
03427   ULONGEST offset = 0;
03428   gdb_byte buf[MAX_TRACE_UPLOAD];
03429 #define MAX_TRACE_UPLOAD 2000
03430   int written;
03431   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
03432 
03433   /* If the target is to save the data to a file on its own, then just
03434      send the command and be done with it.  */
03435   if (target_does_save)
03436     {
03437       if (!writer->ops->target_save (writer, filename))
03438         error (_("Target failed to save trace data to '%s'."),
03439                filename);
03440       return;
03441     }
03442 
03443   /* Get the trace status first before opening the file, so if the
03444      target is losing, we can get out without touching files.  */
03445   status = target_get_trace_status (ts);
03446 
03447   writer->ops->start (writer, filename);
03448 
03449   writer->ops->write_header (writer);
03450 
03451   /* Write descriptive info.  */
03452 
03453   /* Write out the size of a register block.  */
03454   writer->ops->write_regblock_type (writer, trace_regblock_size);
03455 
03456   /* Write out status of the tracing run (aka "tstatus" info).  */
03457   writer->ops->write_status (writer, ts);
03458 
03459   /* Note that we want to upload tracepoints and save those, rather
03460      than simply writing out the local ones, because the user may have
03461      changed tracepoints in GDB in preparation for a future tracing
03462      run, or maybe just mass-deleted all types of breakpoints as part
03463      of cleaning up.  So as not to contaminate the session, leave the
03464      data in its uploaded form, don't make into real tracepoints.  */
03465 
03466   /* Get trace state variables first, they may be checked when parsing
03467      uploaded commands.  */
03468 
03469   target_upload_trace_state_variables (&uploaded_tsvs);
03470 
03471   for (utsv = uploaded_tsvs; utsv; utsv = utsv->next)
03472     writer->ops->write_uploaded_tsv (writer, utsv);
03473 
03474   free_uploaded_tsvs (&uploaded_tsvs);
03475 
03476   target_upload_tracepoints (&uploaded_tps);
03477 
03478   for (utp = uploaded_tps; utp; utp = utp->next)
03479     target_get_tracepoint_status (NULL, utp);
03480 
03481   for (utp = uploaded_tps; utp; utp = utp->next)
03482     writer->ops->write_uploaded_tp (writer, utp);
03483 
03484   free_uploaded_tps (&uploaded_tps);
03485 
03486   /* Mark the end of the definition section.  */
03487   writer->ops->write_definition_end (writer);
03488 
03489   /* Get and write the trace data proper.  */
03490   while (1)
03491     {
03492       LONGEST gotten = 0;
03493 
03494       /* The writer supports writing the contents of trace buffer
03495           directly to trace file.  Don't parse the contents of trace
03496           buffer.  */
03497       if (writer->ops->write_trace_buffer != NULL)
03498         {
03499           /* We ask for big blocks, in the hopes of efficiency, but
03500              will take less if the target has packet size limitations
03501              or some such.  */
03502           gotten = target_get_raw_trace_data (buf, offset,
03503                                               MAX_TRACE_UPLOAD);
03504           if (gotten < 0)
03505             error (_("Failure to get requested trace buffer data"));
03506           /* No more data is forthcoming, we're done.  */
03507           if (gotten == 0)
03508             break;
03509 
03510           writer->ops->write_trace_buffer (writer, buf, gotten);
03511 
03512           offset += gotten;
03513         }
03514       else
03515         {
03516           uint16_t tp_num;
03517           uint32_t tf_size;
03518           /* Parse the trace buffers according to how data are stored
03519              in trace buffer in GDBserver.  */
03520 
03521           gotten = target_get_raw_trace_data (buf, offset, 6);
03522 
03523           if (gotten == 0)
03524             break;
03525 
03526           /* Read the first six bytes in, which is the tracepoint
03527              number and trace frame size.  */
03528           tp_num = (uint16_t)
03529             extract_unsigned_integer (&buf[0], 2, byte_order);
03530 
03531           tf_size = (uint32_t)
03532             extract_unsigned_integer (&buf[2], 4, byte_order);
03533 
03534           writer->ops->frame_ops->start (writer, tp_num);
03535           gotten = 6;
03536 
03537           if (tf_size > 0)
03538             {
03539               unsigned int block;
03540 
03541               offset += 6;
03542 
03543               for (block = 0; block < tf_size; )
03544                 {
03545                   gdb_byte block_type;
03546 
03547                   /* We'll fetch one block each time, in order to
03548                      handle the extremely large 'M' block.  We first
03549                      fetch one byte to get the type of the block.  */
03550                   gotten = target_get_raw_trace_data (buf, offset, 1);
03551                   if (gotten < 1)
03552                     error (_("Failure to get requested trace buffer data"));
03553 
03554                   gotten = 1;
03555                   block += 1;
03556                   offset += 1;
03557 
03558                   block_type = buf[0];
03559                   switch (block_type)
03560                     {
03561                     case 'R':
03562                       gotten
03563                         = target_get_raw_trace_data (buf, offset,
03564                                                      trace_regblock_size);
03565                       if (gotten < trace_regblock_size)
03566                         error (_("Failure to get requested trace"
03567                                  " buffer data"));
03568 
03569                       TRACE_WRITE_R_BLOCK (writer, buf,
03570                                            trace_regblock_size);
03571                       break;
03572                     case 'M':
03573                       {
03574                         unsigned short mlen;
03575                         ULONGEST addr;
03576                         LONGEST t;
03577                         int j;
03578 
03579                         t = target_get_raw_trace_data (buf,offset, 10);
03580                         if (t < 10)
03581                           error (_("Failure to get requested trace"
03582                                    " buffer data"));
03583 
03584                         offset += 10;
03585                         block += 10;
03586 
03587                         gotten = 0;
03588                         addr = (ULONGEST)
03589                           extract_unsigned_integer (buf, 8,
03590                                                     byte_order);
03591                         mlen = (unsigned short)
03592                           extract_unsigned_integer (&buf[8], 2,
03593                                                     byte_order);
03594 
03595                         TRACE_WRITE_M_BLOCK_HEADER (writer, addr,
03596                                                     mlen);
03597 
03598                         /* The memory contents in 'M' block may be
03599                            very large.  Fetch the data from the target
03600                            and write them into file one by one.  */
03601                         for (j = 0; j < mlen; )
03602                           {
03603                             unsigned int read_length;
03604 
03605                             if (mlen - j > MAX_TRACE_UPLOAD)
03606                               read_length = MAX_TRACE_UPLOAD;
03607                             else
03608                               read_length = mlen - j;
03609 
03610                             t = target_get_raw_trace_data (buf,
03611                                                            offset + j,
03612                                                            read_length);
03613                             if (t < read_length)
03614                               error (_("Failure to get requested"
03615                                        " trace buffer data"));
03616 
03617                             TRACE_WRITE_M_BLOCK_MEMORY (writer, buf,
03618                                                         read_length);
03619 
03620                             j += read_length;
03621                             gotten += read_length;
03622                           }
03623 
03624                         break;
03625                       }
03626                     case 'V':
03627                       {
03628                         int vnum;
03629                         LONGEST val;
03630 
03631                         gotten
03632                           = target_get_raw_trace_data (buf, offset,
03633                                                        12);
03634                         if (gotten < 12)
03635                           error (_("Failure to get requested"
03636                                    " trace buffer data"));
03637 
03638                         vnum  = (int) extract_signed_integer (buf,
03639                                                               4,
03640                                                               byte_order);
03641                         val
03642                           = extract_signed_integer (&buf[4], 8,
03643                                                     byte_order);
03644 
03645                         TRACE_WRITE_V_BLOCK (writer, vnum, val);
03646                       }
03647                       break;
03648                     default:
03649                       error (_("Unknown block type '%c' (0x%x) in"
03650                                " trace frame"),
03651                              block_type, block_type);
03652                     }
03653 
03654                   block += gotten;
03655                   offset += gotten;
03656                 }
03657             }
03658           else
03659             offset += gotten;
03660 
03661           writer->ops->frame_ops->end (writer);
03662         }
03663     }
03664 
03665   writer->ops->end (writer);
03666 }
03667 
03668 /* Return a trace writer for TFILE format.  */
03669 
03670 static struct trace_file_writer *
03671 tfile_trace_file_writer_new (void)
03672 {
03673   struct tfile_trace_file_writer *writer
03674     = xmalloc (sizeof (struct tfile_trace_file_writer));
03675 
03676   writer->base.ops = &tfile_write_ops;
03677   writer->fp = NULL;
03678   writer->pathname = NULL;
03679 
03680   return (struct trace_file_writer *) writer;
03681 }
03682 
03683 static void
03684 trace_save_command (char *args, int from_tty)
03685 {
03686   int target_does_save = 0;
03687   char **argv;
03688   char *filename = NULL;
03689   struct cleanup *back_to;
03690   int generate_ctf = 0;
03691   struct trace_file_writer *writer = NULL;
03692 
03693   if (args == NULL)
03694     error_no_arg (_("file in which to save trace data"));
03695 
03696   argv = gdb_buildargv (args);
03697   back_to = make_cleanup_freeargv (argv);
03698 
03699   for (; *argv; ++argv)
03700     {
03701       if (strcmp (*argv, "-r") == 0)
03702         target_does_save = 1;
03703       if (strcmp (*argv, "-ctf") == 0)
03704         generate_ctf = 1;
03705       else if (**argv == '-')
03706         error (_("unknown option `%s'"), *argv);
03707       else
03708         filename = *argv;
03709     }
03710 
03711   if (!filename)
03712     error_no_arg (_("file in which to save trace data"));
03713 
03714   if (generate_ctf)
03715     writer = ctf_trace_file_writer_new ();
03716   else
03717     writer = tfile_trace_file_writer_new ();
03718 
03719   make_cleanup (trace_file_writer_xfree, writer);
03720 
03721   trace_save (filename, writer, target_does_save);
03722 
03723   if (from_tty)
03724     printf_filtered (_("Trace data saved to %s '%s'.\n"),
03725                      generate_ctf ? "directory" : "file", filename);
03726 
03727   do_cleanups (back_to);
03728 }
03729 
03730 /* Save the trace data to file FILENAME of tfile format.  */
03731 
03732 void
03733 trace_save_tfile (const char *filename, int target_does_save)
03734 {
03735   struct trace_file_writer *writer;
03736   struct cleanup *back_to;
03737 
03738   writer = tfile_trace_file_writer_new ();
03739   back_to = make_cleanup (trace_file_writer_xfree, writer);
03740   trace_save (filename, writer, target_does_save);
03741   do_cleanups (back_to);
03742 }
03743 
03744 /* Save the trace data to dir DIRNAME of ctf format.  */
03745 
03746 void
03747 trace_save_ctf (const char *dirname, int target_does_save)
03748 {
03749   struct trace_file_writer *writer;
03750   struct cleanup *back_to;
03751 
03752   writer = ctf_trace_file_writer_new ();
03753   back_to = make_cleanup (trace_file_writer_xfree, writer);
03754 
03755   trace_save (dirname, writer, target_does_save);
03756   do_cleanups (back_to);
03757 }
03758 
03759 /* Tell the target what to do with an ongoing tracing run if GDB
03760    disconnects for some reason.  */
03761 
03762 static void
03763 set_disconnected_tracing (char *args, int from_tty,
03764                           struct cmd_list_element *c)
03765 {
03766   target_set_disconnected_tracing (disconnected_tracing);
03767 }
03768 
03769 static void
03770 set_circular_trace_buffer (char *args, int from_tty,
03771                            struct cmd_list_element *c)
03772 {
03773   target_set_circular_trace_buffer (circular_trace_buffer);
03774 }
03775 
03776 static void
03777 set_trace_buffer_size (char *args, int from_tty,
03778                            struct cmd_list_element *c)
03779 {
03780   target_set_trace_buffer_size (trace_buffer_size);
03781 }
03782 
03783 static void
03784 set_trace_user (char *args, int from_tty,
03785                 struct cmd_list_element *c)
03786 {
03787   int ret;
03788 
03789   ret = target_set_trace_notes (trace_user, NULL, NULL);
03790 
03791   if (!ret)
03792     warning (_("Target does not support trace notes, user ignored"));
03793 }
03794 
03795 static void
03796 set_trace_notes (char *args, int from_tty,
03797                  struct cmd_list_element *c)
03798 {
03799   int ret;
03800 
03801   ret = target_set_trace_notes (NULL, trace_notes, NULL);
03802 
03803   if (!ret)
03804     warning (_("Target does not support trace notes, note ignored"));
03805 }
03806 
03807 static void
03808 set_trace_stop_notes (char *args, int from_tty,
03809                       struct cmd_list_element *c)
03810 {
03811   int ret;
03812 
03813   ret = target_set_trace_notes (NULL, NULL, trace_stop_notes);
03814 
03815   if (!ret)
03816     warning (_("Target does not support trace notes, stop note ignored"));
03817 }
03818 
03819 /* Convert the memory pointed to by mem into hex, placing result in buf.
03820  * Return a pointer to the last char put in buf (null)
03821  * "stolen" from sparc-stub.c
03822  */
03823 
03824 static const char hexchars[] = "0123456789abcdef";
03825 
03826 static char *
03827 mem2hex (gdb_byte *mem, char *buf, int count)
03828 {
03829   gdb_byte ch;
03830 
03831   while (count-- > 0)
03832     {
03833       ch = *mem++;
03834 
03835       *buf++ = hexchars[ch >> 4];
03836       *buf++ = hexchars[ch & 0xf];
03837     }
03838 
03839   *buf = 0;
03840 
03841   return buf;
03842 }
03843 
03844 int
03845 get_traceframe_number (void)
03846 {
03847   return traceframe_number;
03848 }
03849 
03850 int
03851 get_tracepoint_number (void)
03852 {
03853   return tracepoint_number;
03854 }
03855 
03856 /* Make the traceframe NUM be the current trace frame.  Does nothing
03857    if NUM is already current.  */
03858 
03859 void
03860 set_current_traceframe (int num)
03861 {
03862   int newnum;
03863 
03864   if (traceframe_number == num)
03865     {
03866       /* Nothing to do.  */
03867       return;
03868     }
03869 
03870   newnum = target_trace_find (tfind_number, num, 0, 0, NULL);
03871 
03872   if (newnum != num)
03873     warning (_("could not change traceframe"));
03874 
03875   set_traceframe_num (newnum);
03876 
03877   /* Changing the traceframe changes our view of registers and of the
03878      frame chain.  */
03879   registers_changed ();
03880 
03881   clear_traceframe_info ();
03882 }
03883 
03884 /* Make the traceframe NUM be the current trace frame, and do nothing
03885    more.  */
03886 
03887 void
03888 set_traceframe_number (int num)
03889 {
03890   traceframe_number = num;
03891 }
03892 
03893 /* A cleanup used when switching away and back from tfind mode.  */
03894 
03895 struct current_traceframe_cleanup
03896 {
03897   /* The traceframe we were inspecting.  */
03898   int traceframe_number;
03899 };
03900 
03901 static void
03902 do_restore_current_traceframe_cleanup (void *arg)
03903 {
03904   struct current_traceframe_cleanup *old = arg;
03905 
03906   set_current_traceframe (old->traceframe_number);
03907 }
03908 
03909 static void
03910 restore_current_traceframe_cleanup_dtor (void *arg)
03911 {
03912   struct current_traceframe_cleanup *old = arg;
03913 
03914   xfree (old);
03915 }
03916 
03917 struct cleanup *
03918 make_cleanup_restore_current_traceframe (void)
03919 {
03920   struct current_traceframe_cleanup *old;
03921 
03922   old = xmalloc (sizeof (struct current_traceframe_cleanup));
03923   old->traceframe_number = traceframe_number;
03924 
03925   return make_cleanup_dtor (do_restore_current_traceframe_cleanup, old,
03926                             restore_current_traceframe_cleanup_dtor);
03927 }
03928 
03929 struct cleanup *
03930 make_cleanup_restore_traceframe_number (void)
03931 {
03932   return make_cleanup_restore_integer (&traceframe_number);
03933 }
03934 
03935 /* Given a number and address, return an uploaded tracepoint with that
03936    number, creating if necessary.  */
03937 
03938 struct uploaded_tp *
03939 get_uploaded_tp (int num, ULONGEST addr, struct uploaded_tp **utpp)
03940 {
03941   struct uploaded_tp *utp;
03942 
03943   for (utp = *utpp; utp; utp = utp->next)
03944     if (utp->number == num && utp->addr == addr)
03945       return utp;
03946   utp = (struct uploaded_tp *) xmalloc (sizeof (struct uploaded_tp));
03947   memset (utp, 0, sizeof (struct uploaded_tp));
03948   utp->number = num;
03949   utp->addr = addr;
03950   utp->actions = NULL;
03951   utp->step_actions = NULL;
03952   utp->cmd_strings = NULL;
03953   utp->next = *utpp;
03954   *utpp = utp;
03955   return utp;
03956 }
03957 
03958 static void
03959 free_uploaded_tps (struct uploaded_tp **utpp)
03960 {
03961   struct uploaded_tp *next_one;
03962 
03963   while (*utpp)
03964     {
03965       next_one = (*utpp)->next;
03966       xfree (*utpp);
03967       *utpp = next_one;
03968     }
03969 }
03970 
03971 /* Given a number and address, return an uploaded tracepoint with that
03972    number, creating if necessary.  */
03973 
03974 struct uploaded_tsv *
03975 get_uploaded_tsv (int num, struct uploaded_tsv **utsvp)
03976 {
03977   struct uploaded_tsv *utsv;
03978 
03979   for (utsv = *utsvp; utsv; utsv = utsv->next)
03980     if (utsv->number == num)
03981       return utsv;
03982   utsv = (struct uploaded_tsv *) xmalloc (sizeof (struct uploaded_tsv));
03983   memset (utsv, 0, sizeof (struct uploaded_tsv));
03984   utsv->number = num;
03985   utsv->next = *utsvp;
03986   *utsvp = utsv;
03987   return utsv;
03988 }
03989 
03990 static void
03991 free_uploaded_tsvs (struct uploaded_tsv **utsvp)
03992 {
03993   struct uploaded_tsv *next_one;
03994 
03995   while (*utsvp)
03996     {
03997       next_one = (*utsvp)->next;
03998       xfree (*utsvp);
03999       *utsvp = next_one;
04000     }
04001 }
04002 
04003 /* FIXME this function is heuristic and will miss the cases where the
04004    conditional is semantically identical but differs in whitespace,
04005    such as "x == 0" vs "x==0".  */
04006 
04007 static int
04008 cond_string_is_same (char *str1, char *str2)
04009 {
04010   if (str1 == NULL || str2 == NULL)
04011     return (str1 == str2);
04012 
04013   return (strcmp (str1, str2) == 0);
04014 }
04015 
04016 /* Look for an existing tracepoint that seems similar enough to the
04017    uploaded one.  Enablement isn't compared, because the user can
04018    toggle that freely, and may have done so in anticipation of the
04019    next trace run.  Return the location of matched tracepoint.  */
04020 
04021 static struct bp_location *
04022 find_matching_tracepoint_location (struct uploaded_tp *utp)
04023 {
04024   VEC(breakpoint_p) *tp_vec = all_tracepoints ();
04025   int ix;
04026   struct breakpoint *b;
04027   struct bp_location *loc;
04028 
04029   for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, b); ix++)
04030     {
04031       struct tracepoint *t = (struct tracepoint *) b;
04032 
04033       if (b->type == utp->type
04034           && t->step_count == utp->step
04035           && t->pass_count == utp->pass
04036           && cond_string_is_same (t->base.cond_string, utp->cond_string)
04037           /* FIXME also test actions.  */
04038           )
04039         {
04040           /* Scan the locations for an address match.  */
04041           for (loc = b->loc; loc; loc = loc->next)
04042             {
04043               if (loc->address == utp->addr)
04044                 return loc;
04045             }
04046         }
04047     }
04048   return NULL;
04049 }
04050 
04051 /* Given a list of tracepoints uploaded from a target, attempt to
04052    match them up with existing tracepoints, and create new ones if not
04053    found.  */
04054 
04055 void
04056 merge_uploaded_tracepoints (struct uploaded_tp **uploaded_tps)
04057 {
04058   struct uploaded_tp *utp;
04059   /* A set of tracepoints which are modified.  */
04060   VEC(breakpoint_p) *modified_tp = NULL;
04061   int ix;
04062   struct breakpoint *b;
04063 
04064   /* Look for GDB tracepoints that match up with our uploaded versions.  */
04065   for (utp = *uploaded_tps; utp; utp = utp->next)
04066     {
04067       struct bp_location *loc;
04068       struct tracepoint *t;
04069 
04070       loc = find_matching_tracepoint_location (utp);
04071       if (loc)
04072         {
04073           int found = 0;
04074 
04075           /* Mark this location as already inserted.  */
04076           loc->inserted = 1;
04077           t = (struct tracepoint *) loc->owner;
04078           printf_filtered (_("Assuming tracepoint %d is same "
04079                              "as target's tracepoint %d at %s.\n"),
04080                            loc->owner->number, utp->number,
04081                            paddress (loc->gdbarch, utp->addr));
04082 
04083           /* The tracepoint LOC->owner was modified (the location LOC
04084              was marked as inserted in the target).  Save it in
04085              MODIFIED_TP if not there yet.  The 'breakpoint-modified'
04086              observers will be notified later once for each tracepoint
04087              saved in MODIFIED_TP.  */
04088           for (ix = 0;
04089                VEC_iterate (breakpoint_p, modified_tp, ix, b);
04090                ix++)
04091             if (b == loc->owner)
04092               {
04093                 found = 1;
04094                 break;
04095               }
04096           if (!found)
04097             VEC_safe_push (breakpoint_p, modified_tp, loc->owner);
04098         }
04099       else
04100         {
04101           t = create_tracepoint_from_upload (utp);
04102           if (t)
04103             printf_filtered (_("Created tracepoint %d for "
04104                                "target's tracepoint %d at %s.\n"),
04105                              t->base.number, utp->number,
04106                              paddress (get_current_arch (), utp->addr));
04107           else
04108             printf_filtered (_("Failed to create tracepoint for target's "
04109                                "tracepoint %d at %s, skipping it.\n"),
04110                              utp->number,
04111                              paddress (get_current_arch (), utp->addr));
04112         }
04113       /* Whether found or created, record the number used by the
04114          target, to help with mapping target tracepoints back to their
04115          counterparts here.  */
04116       if (t)
04117         t->number_on_target = utp->number;
04118     }
04119 
04120   /* Notify 'breakpoint-modified' observer that at least one of B's
04121      locations was changed.  */
04122   for (ix = 0; VEC_iterate (breakpoint_p, modified_tp, ix, b); ix++)
04123     observer_notify_breakpoint_modified (b);
04124 
04125   VEC_free (breakpoint_p, modified_tp);
04126   free_uploaded_tps (uploaded_tps);
04127 }
04128 
04129 /* Trace state variables don't have much to identify them beyond their
04130    name, so just use that to detect matches.  */
04131 
04132 static struct trace_state_variable *
04133 find_matching_tsv (struct uploaded_tsv *utsv)
04134 {
04135   if (!utsv->name)
04136     return NULL;
04137 
04138   return find_trace_state_variable (utsv->name);
04139 }
04140 
04141 static struct trace_state_variable *
04142 create_tsv_from_upload (struct uploaded_tsv *utsv)
04143 {
04144   const char *namebase;
04145   char *buf;
04146   int try_num = 0;
04147   struct trace_state_variable *tsv;
04148   struct cleanup *old_chain;
04149 
04150   if (utsv->name)
04151     {
04152       namebase = utsv->name;
04153       buf = xstrprintf ("%s", namebase);
04154     }
04155   else
04156     {
04157       namebase = "__tsv";
04158       buf = xstrprintf ("%s_%d", namebase, try_num++);
04159     }
04160 
04161   /* Fish for a name that is not in use.  */
04162   /* (should check against all internal vars?)  */
04163   while (find_trace_state_variable (buf))
04164     {
04165       xfree (buf);
04166       buf = xstrprintf ("%s_%d", namebase, try_num++);
04167     }
04168 
04169   old_chain = make_cleanup (xfree, buf);
04170 
04171   /* We have an available name, create the variable.  */
04172   tsv = create_trace_state_variable (buf);
04173   tsv->initial_value = utsv->initial_value;
04174   tsv->builtin = utsv->builtin;
04175 
04176   observer_notify_tsv_created (tsv);
04177 
04178   do_cleanups (old_chain);
04179 
04180   return tsv;
04181 }
04182 
04183 /* Given a list of uploaded trace state variables, try to match them
04184    up with existing variables, or create additional ones.  */
04185 
04186 void
04187 merge_uploaded_trace_state_variables (struct uploaded_tsv **uploaded_tsvs)
04188 {
04189   int ix;
04190   struct uploaded_tsv *utsv;
04191   struct trace_state_variable *tsv;
04192   int highest;
04193 
04194   /* Most likely some numbers will have to be reassigned as part of
04195      the merge, so clear them all in anticipation.  */
04196   for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
04197     tsv->number = 0;
04198 
04199   for (utsv = *uploaded_tsvs; utsv; utsv = utsv->next)
04200     {
04201       tsv = find_matching_tsv (utsv);
04202       if (tsv)
04203         {
04204           if (info_verbose)
04205             printf_filtered (_("Assuming trace state variable $%s "
04206                                "is same as target's variable %d.\n"),
04207                              tsv->name, utsv->number);
04208         }
04209       else
04210         {
04211           tsv = create_tsv_from_upload (utsv);
04212           if (info_verbose)
04213             printf_filtered (_("Created trace state variable "
04214                                "$%s for target's variable %d.\n"),
04215                              tsv->name, utsv->number);
04216         }
04217       /* Give precedence to numberings that come from the target.  */
04218       if (tsv)
04219         tsv->number = utsv->number;
04220     }
04221 
04222   /* Renumber everything that didn't get a target-assigned number.  */
04223   highest = 0;
04224   for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
04225     if (tsv->number > highest)
04226       highest = tsv->number;
04227 
04228   ++highest;
04229   for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
04230     if (tsv->number == 0)
04231       tsv->number = highest++;
04232 
04233   free_uploaded_tsvs (uploaded_tsvs);
04234 }
04235 
04236 /* target tfile command */
04237 
04238 static struct target_ops tfile_ops;
04239 
04240 /* Fill in tfile_ops with its defined operations and properties.  */
04241 
04242 #define TRACE_HEADER_SIZE 8
04243 
04244 static char *trace_filename;
04245 static int trace_fd = -1;
04246 static off_t trace_frames_offset;
04247 static off_t cur_offset;
04248 static int cur_data_size;
04249 int trace_regblock_size;
04250 
04251 static void tfile_interp_line (char *line,
04252                                struct uploaded_tp **utpp,
04253                                struct uploaded_tsv **utsvp);
04254 
04255 /* Read SIZE bytes into READBUF from the trace frame, starting at
04256    TRACE_FD's current position.  Note that this call `read'
04257    underneath, hence it advances the file's seek position.  Throws an
04258    error if the `read' syscall fails, or less than SIZE bytes are
04259    read.  */
04260 
04261 static void
04262 tfile_read (gdb_byte *readbuf, int size)
04263 {
04264   int gotten;
04265 
04266   gotten = read (trace_fd, readbuf, size);
04267   if (gotten < 0)
04268     perror_with_name (trace_filename);
04269   else if (gotten < size)
04270     error (_("Premature end of file while reading trace file"));
04271 }
04272 
04273 static void
04274 tfile_open (char *filename, int from_tty)
04275 {
04276   volatile struct gdb_exception ex;
04277   char *temp;
04278   struct cleanup *old_chain;
04279   int flags;
04280   int scratch_chan;
04281   char header[TRACE_HEADER_SIZE];
04282   char linebuf[1000]; /* Should be max remote packet size or so.  */
04283   gdb_byte byte;
04284   int bytes, i;
04285   struct trace_status *ts;
04286   struct uploaded_tp *uploaded_tps = NULL;
04287   struct uploaded_tsv *uploaded_tsvs = NULL;
04288 
04289   target_preopen (from_tty);
04290   if (!filename)
04291     error (_("No trace file specified."));
04292 
04293   filename = tilde_expand (filename);
04294   if (!IS_ABSOLUTE_PATH(filename))
04295     {
04296       temp = concat (current_directory, "/", filename, (char *) NULL);
04297       xfree (filename);
04298       filename = temp;
04299     }
04300 
04301   old_chain = make_cleanup (xfree, filename);
04302 
04303   flags = O_BINARY | O_LARGEFILE;
04304   flags |= O_RDONLY;
04305   scratch_chan = gdb_open_cloexec (filename, flags, 0);
04306   if (scratch_chan < 0)
04307     perror_with_name (filename);
04308 
04309   /* Looks semi-reasonable.  Toss the old trace file and work on the new.  */
04310 
04311   discard_cleanups (old_chain); /* Don't free filename any more.  */
04312   unpush_target (&tfile_ops);
04313 
04314   trace_filename = xstrdup (filename);
04315   trace_fd = scratch_chan;
04316 
04317   bytes = 0;
04318   /* Read the file header and test for validity.  */
04319   tfile_read ((gdb_byte *) &header, TRACE_HEADER_SIZE);
04320 
04321   bytes += TRACE_HEADER_SIZE;
04322   if (!(header[0] == 0x7f
04323         && (strncmp (header + 1, "TRACE0\n", 7) == 0)))
04324     error (_("File is not a valid trace file."));
04325 
04326   push_target (&tfile_ops);
04327 
04328   trace_regblock_size = 0;
04329   ts = current_trace_status ();
04330   /* We know we're working with a file.  Record its name.  */
04331   ts->filename = trace_filename;
04332   /* Set defaults in case there is no status line.  */
04333   ts->running_known = 0;
04334   ts->stop_reason = trace_stop_reason_unknown;
04335   ts->traceframe_count = -1;
04336   ts->buffer_free = 0;
04337   ts->disconnected_tracing = 0;
04338   ts->circular_buffer = 0;
04339 
04340   TRY_CATCH (ex, RETURN_MASK_ALL)
04341     {
04342       /* Read through a section of newline-terminated lines that
04343          define things like tracepoints.  */
04344       i = 0;
04345       while (1)
04346         {
04347           tfile_read (&byte, 1);
04348 
04349           ++bytes;
04350           if (byte == '\n')
04351             {
04352               /* Empty line marks end of the definition section.  */
04353               if (i == 0)
04354                 break;
04355               linebuf[i] = '\0';
04356               i = 0;
04357               tfile_interp_line (linebuf, &uploaded_tps, &uploaded_tsvs);
04358             }
04359           else
04360             linebuf[i++] = byte;
04361           if (i >= 1000)
04362             error (_("Excessively long lines in trace file"));
04363         }
04364 
04365       /* Record the starting offset of the binary trace data.  */
04366       trace_frames_offset = bytes;
04367 
04368       /* If we don't have a blocksize, we can't interpret the
04369          traceframes.  */
04370       if (trace_regblock_size == 0)
04371         error (_("No register block size recorded in trace file"));
04372     }
04373   if (ex.reason < 0)
04374     {
04375       /* Remove the partially set up target.  */
04376       unpush_target (&tfile_ops);
04377       throw_exception (ex);
04378     }
04379 
04380   if (ts->traceframe_count <= 0)
04381     warning (_("No traceframes present in this file."));
04382 
04383   /* Add the file's tracepoints and variables into the current mix.  */
04384 
04385   /* Get trace state variables first, they may be checked when parsing
04386      uploaded commands.  */
04387   merge_uploaded_trace_state_variables (&uploaded_tsvs);
04388 
04389   merge_uploaded_tracepoints (&uploaded_tps);
04390 }
04391 
04392 /* Interpret the given line from the definitions part of the trace
04393    file.  */
04394 
04395 static void
04396 tfile_interp_line (char *line, struct uploaded_tp **utpp,
04397                    struct uploaded_tsv **utsvp)
04398 {
04399   char *p = line;
04400 
04401   if (strncmp (p, "R ", strlen ("R ")) == 0)
04402     {
04403       p += strlen ("R ");
04404       trace_regblock_size = strtol (p, &p, 16);
04405     }
04406   else if (strncmp (p, "status ", strlen ("status ")) == 0)
04407     {
04408       p += strlen ("status ");
04409       parse_trace_status (p, current_trace_status ());
04410     }
04411   else if (strncmp (p, "tp ", strlen ("tp ")) == 0)
04412     {
04413       p += strlen ("tp ");
04414       parse_tracepoint_definition (p, utpp);
04415     }
04416   else if (strncmp (p, "tsv ", strlen ("tsv ")) == 0)
04417     {
04418       p += strlen ("tsv ");
04419       parse_tsv_definition (p, utsvp);
04420     }
04421   else
04422     warning (_("Ignoring trace file definition \"%s\""), line);
04423 }
04424 
04425 /* Parse the part of trace status syntax that is shared between
04426    the remote protocol and the trace file reader.  */
04427 
04428 void
04429 parse_trace_status (char *line, struct trace_status *ts)
04430 {
04431   char *p = line, *p1, *p2, *p3, *p_temp;
04432   int end;
04433   ULONGEST val;
04434 
04435   ts->running_known = 1;
04436   ts->running = (*p++ == '1');
04437   ts->stop_reason = trace_stop_reason_unknown;
04438   xfree (ts->stop_desc);
04439   ts->stop_desc = NULL;
04440   ts->traceframe_count = -1;
04441   ts->traceframes_created = -1;
04442   ts->buffer_free = -1;
04443   ts->buffer_size = -1;
04444   ts->disconnected_tracing = 0;
04445   ts->circular_buffer = 0;
04446   xfree (ts->user_name);
04447   ts->user_name = NULL;
04448   xfree (ts->notes);
04449   ts->notes = NULL;
04450   ts->start_time = ts->stop_time = 0;
04451 
04452   while (*p++)
04453     {
04454       p1 = strchr (p, ':');
04455       if (p1 == NULL)
04456         error (_("Malformed trace status, at %s\n\
04457 Status line: '%s'\n"), p, line);
04458       p3 = strchr (p, ';');
04459       if (p3 == NULL)
04460         p3 = p + strlen (p);
04461       if (strncmp (p, stop_reason_names[trace_buffer_full], p1 - p) == 0)
04462         {
04463           p = unpack_varlen_hex (++p1, &val);
04464           ts->stop_reason = trace_buffer_full;
04465         }
04466       else if (strncmp (p, stop_reason_names[trace_never_run], p1 - p) == 0)
04467         {
04468           p = unpack_varlen_hex (++p1, &val);
04469           ts->stop_reason = trace_never_run;
04470         }
04471       else if (strncmp (p, stop_reason_names[tracepoint_passcount],
04472                         p1 - p) == 0)
04473         {
04474           p = unpack_varlen_hex (++p1, &val);
04475           ts->stop_reason = tracepoint_passcount;
04476           ts->stopping_tracepoint = val;
04477         }
04478       else if (strncmp (p, stop_reason_names[tstop_command], p1 - p) == 0)
04479         {
04480           p2 = strchr (++p1, ':');
04481           if (!p2 || p2 > p3)
04482             {
04483               /*older style*/
04484               p2 = p1;
04485             }
04486           else if (p2 != p1)
04487             {
04488               ts->stop_desc = xmalloc (strlen (line));
04489               end = hex2bin (p1, (gdb_byte *) ts->stop_desc, (p2 - p1) / 2);
04490               ts->stop_desc[end] = '\0';
04491             }
04492           else
04493             ts->stop_desc = xstrdup ("");
04494 
04495           p = unpack_varlen_hex (++p2, &val);
04496           ts->stop_reason = tstop_command;
04497         }
04498       else if (strncmp (p, stop_reason_names[trace_disconnected], p1 - p) == 0)
04499         {
04500           p = unpack_varlen_hex (++p1, &val);
04501           ts->stop_reason = trace_disconnected;
04502         }
04503       else if (strncmp (p, stop_reason_names[tracepoint_error], p1 - p) == 0)
04504         {
04505           p2 = strchr (++p1, ':');
04506           if (p2 != p1)
04507             {
04508               ts->stop_desc = xmalloc ((p2 - p1) / 2 + 1);
04509               end = hex2bin (p1, (gdb_byte *) ts->stop_desc, (p2 - p1) / 2);
04510               ts->stop_desc[end] = '\0';
04511             }
04512           else
04513             ts->stop_desc = xstrdup ("");
04514 
04515           p = unpack_varlen_hex (++p2, &val);
04516           ts->stopping_tracepoint = val;
04517           ts->stop_reason = tracepoint_error;
04518         }
04519       else if (strncmp (p, "tframes", p1 - p) == 0)
04520         {
04521           p = unpack_varlen_hex (++p1, &val);
04522           ts->traceframe_count = val;
04523         }
04524       else if (strncmp (p, "tcreated", p1 - p) == 0)
04525         {
04526           p = unpack_varlen_hex (++p1, &val);
04527           ts->traceframes_created = val;
04528         }
04529       else if (strncmp (p, "tfree", p1 - p) == 0)
04530         {
04531           p = unpack_varlen_hex (++p1, &val);
04532           ts->buffer_free = val;
04533         }
04534       else if (strncmp (p, "tsize", p1 - p) == 0)
04535         {
04536           p = unpack_varlen_hex (++p1, &val);
04537           ts->buffer_size = val;
04538         }
04539       else if (strncmp (p, "disconn", p1 - p) == 0)
04540         {
04541           p = unpack_varlen_hex (++p1, &val);
04542           ts->disconnected_tracing = val;
04543         }
04544       else if (strncmp (p, "circular", p1 - p) == 0)
04545         {
04546           p = unpack_varlen_hex (++p1, &val);
04547           ts->circular_buffer = val;
04548         }
04549       else if (strncmp (p, "starttime", p1 - p) == 0)
04550         {
04551           p = unpack_varlen_hex (++p1, &val);
04552           ts->start_time = val;
04553         }
04554       else if (strncmp (p, "stoptime", p1 - p) == 0)
04555         {
04556           p = unpack_varlen_hex (++p1, &val);
04557           ts->stop_time = val;
04558         }
04559       else if (strncmp (p, "username", p1 - p) == 0)
04560         {
04561           ++p1;
04562           ts->user_name = xmalloc (strlen (p) / 2);
04563           end = hex2bin (p1, (gdb_byte *) ts->user_name, (p3 - p1)  / 2);
04564           ts->user_name[end] = '\0';
04565           p = p3;
04566         }
04567       else if (strncmp (p, "notes", p1 - p) == 0)
04568         {
04569           ++p1;
04570           ts->notes = xmalloc (strlen (p) / 2);
04571           end = hex2bin (p1, (gdb_byte *) ts->notes, (p3 - p1) / 2);
04572           ts->notes[end] = '\0';
04573           p = p3;
04574         }
04575       else
04576         {
04577           /* Silently skip unknown optional info.  */
04578           p_temp = strchr (p1 + 1, ';');
04579           if (p_temp)
04580             p = p_temp;
04581           else
04582             /* Must be at the end.  */
04583             break;
04584         }
04585     }
04586 }
04587 
04588 void
04589 parse_tracepoint_status (char *p, struct breakpoint *bp,
04590                          struct uploaded_tp *utp)
04591 {
04592   ULONGEST uval;
04593   struct tracepoint *tp = (struct tracepoint *) bp;
04594 
04595   p = unpack_varlen_hex (p, &uval);
04596   if (tp)
04597     tp->base.hit_count += uval;
04598   else
04599     utp->hit_count += uval;
04600   p = unpack_varlen_hex (p + 1, &uval);
04601   if (tp)
04602     tp->traceframe_usage += uval;
04603   else
04604     utp->traceframe_usage += uval;
04605   /* Ignore any extra, allowing for future extensions.  */
04606 }
04607 
04608 /* Given a line of text defining a part of a tracepoint, parse it into
04609    an "uploaded tracepoint".  */
04610 
04611 void
04612 parse_tracepoint_definition (char *line, struct uploaded_tp **utpp)
04613 {
04614   char *p;
04615   char piece;
04616   ULONGEST num, addr, step, pass, orig_size, xlen, start;
04617   int enabled, end;
04618   enum bptype type;
04619   char *cond, *srctype, *buf;
04620   struct uploaded_tp *utp = NULL;
04621 
04622   p = line;
04623   /* Both tracepoint and action definitions start with the same number
04624      and address sequence.  */
04625   piece = *p++;
04626   p = unpack_varlen_hex (p, &num);
04627   p++;  /* skip a colon */
04628   p = unpack_varlen_hex (p, &addr);
04629   p++;  /* skip a colon */
04630   if (piece == 'T')
04631     {
04632       enabled = (*p++ == 'E');
04633       p++;  /* skip a colon */
04634       p = unpack_varlen_hex (p, &step);
04635       p++;  /* skip a colon */
04636       p = unpack_varlen_hex (p, &pass);
04637       type = bp_tracepoint;
04638       cond = NULL;
04639       /* Thumb through optional fields.  */
04640       while (*p == ':')
04641         {
04642           p++;  /* skip a colon */
04643           if (*p == 'F')
04644             {
04645               type = bp_fast_tracepoint;
04646               p++;
04647               p = unpack_varlen_hex (p, &orig_size);
04648             }
04649           else if (*p == 'S')
04650             {
04651               type = bp_static_tracepoint;
04652               p++;
04653             }
04654           else if (*p == 'X')
04655             {
04656               p++;
04657               p = unpack_varlen_hex (p, &xlen);
04658               p++;  /* skip a comma */
04659               cond = (char *) xmalloc (2 * xlen + 1);
04660               strncpy (cond, p, 2 * xlen);
04661               cond[2 * xlen] = '\0';
04662               p += 2 * xlen;
04663             }
04664           else
04665             warning (_("Unrecognized char '%c' in tracepoint "
04666                        "definition, skipping rest"), *p);
04667         }
04668       utp = get_uploaded_tp (num, addr, utpp);
04669       utp->type = type;
04670       utp->enabled = enabled;
04671       utp->step = step;
04672       utp->pass = pass;
04673       utp->cond = cond;
04674     }
04675   else if (piece == 'A')
04676     {
04677       utp = get_uploaded_tp (num, addr, utpp);
04678       VEC_safe_push (char_ptr, utp->actions, xstrdup (p));
04679     }
04680   else if (piece == 'S')
04681     {
04682       utp = get_uploaded_tp (num, addr, utpp);
04683       VEC_safe_push (char_ptr, utp->step_actions, xstrdup (p));
04684     }
04685   else if (piece == 'Z')
04686     {
04687       /* Parse a chunk of source form definition.  */
04688       utp = get_uploaded_tp (num, addr, utpp);
04689       srctype = p;
04690       p = strchr (p, ':');
04691       p++;  /* skip a colon */
04692       p = unpack_varlen_hex (p, &start);
04693       p++;  /* skip a colon */
04694       p = unpack_varlen_hex (p, &xlen);
04695       p++;  /* skip a colon */
04696 
04697       buf = alloca (strlen (line));
04698 
04699       end = hex2bin (p, (gdb_byte *) buf, strlen (p) / 2);
04700       buf[end] = '\0';
04701 
04702       if (strncmp (srctype, "at:", strlen ("at:")) == 0)
04703         utp->at_string = xstrdup (buf);
04704       else if (strncmp (srctype, "cond:", strlen ("cond:")) == 0)
04705         utp->cond_string = xstrdup (buf);
04706       else if (strncmp (srctype, "cmd:", strlen ("cmd:")) == 0)
04707         VEC_safe_push (char_ptr, utp->cmd_strings, xstrdup (buf));
04708     }
04709   else if (piece == 'V')
04710     {
04711       utp = get_uploaded_tp (num, addr, utpp);
04712 
04713       parse_tracepoint_status (p, NULL, utp);
04714     }
04715   else
04716     {
04717       /* Don't error out, the target might be sending us optional
04718          info that we don't care about.  */
04719       warning (_("Unrecognized tracepoint piece '%c', ignoring"), piece);
04720     }
04721 }
04722 
04723 /* Convert a textual description of a trace state variable into an
04724    uploaded object.  */
04725 
04726 void
04727 parse_tsv_definition (char *line, struct uploaded_tsv **utsvp)
04728 {
04729   char *p, *buf;
04730   ULONGEST num, initval, builtin;
04731   int end;
04732   struct uploaded_tsv *utsv = NULL;
04733 
04734   buf = alloca (strlen (line));
04735 
04736   p = line;
04737   p = unpack_varlen_hex (p, &num);
04738   p++; /* skip a colon */
04739   p = unpack_varlen_hex (p, &initval);
04740   p++; /* skip a colon */
04741   p = unpack_varlen_hex (p, &builtin);
04742   p++; /* skip a colon */
04743   end = hex2bin (p, (gdb_byte *) buf, strlen (p) / 2);
04744   buf[end] = '\0';
04745 
04746   utsv = get_uploaded_tsv (num, utsvp);
04747   utsv->initial_value = initval;
04748   utsv->builtin = builtin;
04749   utsv->name = xstrdup (buf);
04750 }
04751 
04752 /* Close the trace file and generally clean up.  */
04753 
04754 static void
04755 tfile_close (void)
04756 {
04757   int pid;
04758 
04759   if (trace_fd < 0)
04760     return;
04761 
04762   close (trace_fd);
04763   trace_fd = -1;
04764   xfree (trace_filename);
04765   trace_filename = NULL;
04766 
04767   trace_reset_local_state ();
04768 }
04769 
04770 static void
04771 tfile_files_info (struct target_ops *t)
04772 {
04773   printf_filtered ("\t`%s'\n", trace_filename);
04774 }
04775 
04776 /* The trace status for a file is that tracing can never be run.  */
04777 
04778 static int
04779 tfile_get_trace_status (struct trace_status *ts)
04780 {
04781   /* Other bits of trace status were collected as part of opening the
04782      trace files, so nothing to do here.  */
04783 
04784   return -1;
04785 }
04786 
04787 static void
04788 tfile_get_tracepoint_status (struct breakpoint *tp, struct uploaded_tp *utp)
04789 {
04790   /* Other bits of trace status were collected as part of opening the
04791      trace files, so nothing to do here.  */
04792 }
04793 
04794 /* Given the position of a traceframe in the file, figure out what
04795    address the frame was collected at.  This would normally be the
04796    value of a collected PC register, but if not available, we
04797    improvise.  */
04798 
04799 static CORE_ADDR
04800 tfile_get_traceframe_address (off_t tframe_offset)
04801 {
04802   CORE_ADDR addr = 0;
04803   short tpnum;
04804   struct tracepoint *tp;
04805   off_t saved_offset = cur_offset;
04806 
04807   /* FIXME dig pc out of collected registers.  */
04808 
04809   /* Fall back to using tracepoint address.  */
04810   lseek (trace_fd, tframe_offset, SEEK_SET);
04811   tfile_read ((gdb_byte *) &tpnum, 2);
04812   tpnum = (short) extract_signed_integer ((gdb_byte *) &tpnum, 2,
04813                                           gdbarch_byte_order
04814                                               (target_gdbarch ()));
04815 
04816   tp = get_tracepoint_by_number_on_target (tpnum);
04817   /* FIXME this is a poor heuristic if multiple locations.  */
04818   if (tp && tp->base.loc)
04819     addr = tp->base.loc->address;
04820 
04821   /* Restore our seek position.  */
04822   cur_offset = saved_offset;
04823   lseek (trace_fd, cur_offset, SEEK_SET);
04824   return addr;
04825 }
04826 
04827 /* Given a type of search and some parameters, scan the collection of
04828    traceframes in the file looking for a match.  When found, return
04829    both the traceframe and tracepoint number, otherwise -1 for
04830    each.  */
04831 
04832 static int
04833 tfile_trace_find (enum trace_find_type type, int num,
04834                   CORE_ADDR addr1, CORE_ADDR addr2, int *tpp)
04835 {
04836   short tpnum;
04837   int tfnum = 0, found = 0;
04838   unsigned int data_size;
04839   struct tracepoint *tp;
04840   off_t offset, tframe_offset;
04841   CORE_ADDR tfaddr;
04842 
04843   if (num == -1)
04844     {
04845       if (tpp)
04846         *tpp = -1;
04847       return -1;
04848     }
04849 
04850   lseek (trace_fd, trace_frames_offset, SEEK_SET);
04851   offset = trace_frames_offset;
04852   while (1)
04853     {
04854       tframe_offset = offset;
04855       tfile_read ((gdb_byte *) &tpnum, 2);
04856       tpnum = (short) extract_signed_integer ((gdb_byte *) &tpnum, 2,
04857                                               gdbarch_byte_order
04858                                                   (target_gdbarch ()));
04859       offset += 2;
04860       if (tpnum == 0)
04861         break;
04862       tfile_read ((gdb_byte *) &data_size, 4);
04863       data_size = (unsigned int) extract_unsigned_integer
04864                                      ((gdb_byte *) &data_size, 4,
04865                                       gdbarch_byte_order (target_gdbarch ()));
04866       offset += 4;
04867 
04868       if (type == tfind_number)
04869         {
04870           /* Looking for a specific trace frame.  */
04871           if (tfnum == num)
04872             found = 1;
04873         }
04874       else
04875         {
04876           /* Start from the _next_ trace frame.  */
04877           if (tfnum > traceframe_number)
04878             {
04879               switch (type)
04880                 {
04881                 case tfind_pc:
04882                   tfaddr = tfile_get_traceframe_address (tframe_offset);
04883                   if (tfaddr == addr1)
04884                     found = 1;
04885                   break;
04886                 case tfind_tp:
04887                   tp = get_tracepoint (num);
04888                   if (tp && tpnum == tp->number_on_target)
04889                     found = 1;
04890                   break;
04891                 case tfind_range:
04892                   tfaddr = tfile_get_traceframe_address (tframe_offset);
04893                   if (addr1 <= tfaddr && tfaddr <= addr2)
04894                     found = 1;
04895                   break;
04896                 case tfind_outside:
04897                   tfaddr = tfile_get_traceframe_address (tframe_offset);
04898                   if (!(addr1 <= tfaddr && tfaddr <= addr2))
04899                     found = 1;
04900                   break;
04901                 default:
04902                   internal_error (__FILE__, __LINE__, _("unknown tfind type"));
04903                 }
04904             }
04905         }
04906 
04907       if (found)
04908         {
04909           if (tpp)
04910             *tpp = tpnum;
04911           cur_offset = offset;
04912           cur_data_size = data_size;
04913 
04914           return tfnum;
04915         }
04916       /* Skip past the traceframe's data.  */
04917       lseek (trace_fd, data_size, SEEK_CUR);
04918       offset += data_size;
04919       /* Update our own count of traceframes.  */
04920       ++tfnum;
04921     }
04922   /* Did not find what we were looking for.  */
04923   if (tpp)
04924     *tpp = -1;
04925   return -1;
04926 }
04927 
04928 /* Prototype of the callback passed to tframe_walk_blocks.  */
04929 typedef int (*walk_blocks_callback_func) (char blocktype, void *data);
04930 
04931 /* Callback for traceframe_walk_blocks, used to find a given block
04932    type in a traceframe.  */
04933 
04934 static int
04935 match_blocktype (char blocktype, void *data)
04936 {
04937   char *wantedp = data;
04938 
04939   if (*wantedp == blocktype)
04940     return 1;
04941 
04942   return 0;
04943 }
04944 
04945 /* Walk over all traceframe block starting at POS offset from
04946    CUR_OFFSET, and call CALLBACK for each block found, passing in DATA
04947    unmodified.  If CALLBACK returns true, this returns the position in
04948    the traceframe where the block is found, relative to the start of
04949    the traceframe (cur_offset).  Returns -1 if no callback call
04950    returned true, indicating that all blocks have been walked.  */
04951 
04952 static int
04953 traceframe_walk_blocks (walk_blocks_callback_func callback,
04954                         int pos, void *data)
04955 {
04956   /* Iterate through a traceframe's blocks, looking for a block of the
04957      requested type.  */
04958 
04959   lseek (trace_fd, cur_offset + pos, SEEK_SET);
04960   while (pos < cur_data_size)
04961     {
04962       unsigned short mlen;
04963       char block_type;
04964 
04965       tfile_read ((gdb_byte *) &block_type, 1);
04966 
04967       ++pos;
04968 
04969       if ((*callback) (block_type, data))
04970         return pos;
04971 
04972       switch (block_type)
04973         {
04974         case 'R':
04975           lseek (trace_fd, cur_offset + pos + trace_regblock_size, SEEK_SET);
04976           pos += trace_regblock_size;
04977           break;
04978         case 'M':
04979           lseek (trace_fd, cur_offset + pos + 8, SEEK_SET);
04980           tfile_read ((gdb_byte *) &mlen, 2);
04981           mlen = (unsigned short)
04982                 extract_unsigned_integer ((gdb_byte *) &mlen, 2,
04983                                           gdbarch_byte_order
04984                                               (target_gdbarch ()));
04985           lseek (trace_fd, mlen, SEEK_CUR);
04986           pos += (8 + 2 + mlen);
04987           break;
04988         case 'V':
04989           lseek (trace_fd, cur_offset + pos + 4 + 8, SEEK_SET);
04990           pos += (4 + 8);
04991           break;
04992         default:
04993           error (_("Unknown block type '%c' (0x%x) in trace frame"),
04994                  block_type, block_type);
04995           break;
04996         }
04997     }
04998 
04999   return -1;
05000 }
05001 
05002 /* Convenience wrapper around traceframe_walk_blocks.  Looks for the
05003    position offset of a block of type TYPE_WANTED in the current trace
05004    frame, starting at POS.  Returns -1 if no such block was found.  */
05005 
05006 static int
05007 traceframe_find_block_type (char type_wanted, int pos)
05008 {
05009   return traceframe_walk_blocks (match_blocktype, pos, &type_wanted);
05010 }
05011 
05012 /* Look for a block of saved registers in the traceframe, and get the
05013    requested register from it.  */
05014 
05015 static void
05016 tfile_fetch_registers (struct target_ops *ops,
05017                        struct regcache *regcache, int regno)
05018 {
05019   struct gdbarch *gdbarch = get_regcache_arch (regcache);
05020   int offset, regn, regsize, pc_regno;
05021   gdb_byte *regs;
05022 
05023   /* An uninitialized reg size says we're not going to be
05024      successful at getting register blocks.  */
05025   if (!trace_regblock_size)
05026     return;
05027 
05028   regs = alloca (trace_regblock_size);
05029 
05030   if (traceframe_find_block_type ('R', 0) >= 0)
05031     {
05032       tfile_read (regs, trace_regblock_size);
05033 
05034       /* Assume the block is laid out in GDB register number order,
05035          each register with the size that it has in GDB.  */
05036       offset = 0;
05037       for (regn = 0; regn < gdbarch_num_regs (gdbarch); regn++)
05038         {
05039           regsize = register_size (gdbarch, regn);
05040           /* Make sure we stay within block bounds.  */
05041           if (offset + regsize >= trace_regblock_size)
05042             break;
05043           if (regcache_register_status (regcache, regn) == REG_UNKNOWN)
05044             {
05045               if (regno == regn)
05046                 {
05047                   regcache_raw_supply (regcache, regno, regs + offset);
05048                   break;
05049                 }
05050               else if (regno == -1)
05051                 {
05052                   regcache_raw_supply (regcache, regn, regs + offset);
05053                 }
05054             }
05055           offset += regsize;
05056         }
05057       return;
05058     }
05059 
05060   /* We get here if no register data has been found.  Mark registers
05061      as unavailable.  */
05062   for (regn = 0; regn < gdbarch_num_regs (gdbarch); regn++)
05063     regcache_raw_supply (regcache, regn, NULL);
05064 
05065   /* We can often usefully guess that the PC is going to be the same
05066      as the address of the tracepoint.  */
05067   pc_regno = gdbarch_pc_regnum (gdbarch);
05068   if (pc_regno >= 0 && (regno == -1 || regno == pc_regno))
05069     {
05070       struct tracepoint *tp = get_tracepoint (tracepoint_number);
05071 
05072       if (tp && tp->base.loc)
05073         {
05074           /* But don't try to guess if tracepoint is multi-location...  */
05075           if (tp->base.loc->next)
05076             {
05077               warning (_("Tracepoint %d has multiple "
05078                          "locations, cannot infer $pc"),
05079                        tp->base.number);
05080               return;
05081             }
05082           /* ... or does while-stepping.  */
05083           if (tp->step_count > 0)
05084             {
05085               warning (_("Tracepoint %d does while-stepping, "
05086                          "cannot infer $pc"),
05087                        tp->base.number);
05088               return;
05089             }
05090 
05091           store_unsigned_integer (regs, register_size (gdbarch, pc_regno),
05092                                   gdbarch_byte_order (gdbarch),
05093                                   tp->base.loc->address);
05094           regcache_raw_supply (regcache, pc_regno, regs);
05095         }
05096     }
05097 }
05098 
05099 static LONGEST
05100 tfile_xfer_partial (struct target_ops *ops, enum target_object object,
05101                     const char *annex, gdb_byte *readbuf,
05102                     const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
05103 {
05104   /* We're only doing regular memory for now.  */
05105   if (object != TARGET_OBJECT_MEMORY)
05106     return -1;
05107 
05108   if (readbuf == NULL)
05109     error (_("tfile_xfer_partial: trace file is read-only"));
05110 
05111  if (traceframe_number != -1)
05112     {
05113       int pos = 0;
05114 
05115       /* Iterate through the traceframe's blocks, looking for
05116          memory.  */
05117       while ((pos = traceframe_find_block_type ('M', pos)) >= 0)
05118         {
05119           ULONGEST maddr, amt;
05120           unsigned short mlen;
05121           enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
05122 
05123           tfile_read ((gdb_byte *) &maddr, 8);
05124           maddr = extract_unsigned_integer ((gdb_byte *) &maddr, 8,
05125                                             byte_order);
05126           tfile_read ((gdb_byte *) &mlen, 2);
05127           mlen = (unsigned short)
05128             extract_unsigned_integer ((gdb_byte *) &mlen, 2, byte_order);
05129 
05130           /* If the block includes the first part of the desired
05131              range, return as much it has; GDB will re-request the
05132              remainder, which might be in a different block of this
05133              trace frame.  */
05134           if (maddr <= offset && offset < (maddr + mlen))
05135             {
05136               amt = (maddr + mlen) - offset;
05137               if (amt > len)
05138                 amt = len;
05139 
05140               if (maddr != offset)
05141                 lseek (trace_fd, offset - maddr, SEEK_CUR);
05142               tfile_read (readbuf, amt);
05143               return amt;
05144             }
05145 
05146           /* Skip over this block.  */
05147           pos += (8 + 2 + mlen);
05148         }
05149     }
05150 
05151   /* It's unduly pedantic to refuse to look at the executable for
05152      read-only pieces; so do the equivalent of readonly regions aka
05153      QTro packet.  */
05154   /* FIXME account for relocation at some point.  */
05155   if (exec_bfd)
05156     {
05157       asection *s;
05158       bfd_size_type size;
05159       bfd_vma vma;
05160 
05161       for (s = exec_bfd->sections; s; s = s->next)
05162         {
05163           if ((s->flags & SEC_LOAD) == 0
05164               || (s->flags & SEC_READONLY) == 0)
05165             continue;
05166 
05167           vma = s->vma;
05168           size = bfd_get_section_size (s);
05169           if (vma <= offset && offset < (vma + size))
05170             {
05171               ULONGEST amt;
05172 
05173               amt = (vma + size) - offset;
05174               if (amt > len)
05175                 amt = len;
05176 
05177               amt = bfd_get_section_contents (exec_bfd, s,
05178                                               readbuf, offset - vma, amt);
05179               return amt;
05180             }
05181         }
05182     }
05183 
05184   /* Indicate failure to find the requested memory block.  */
05185   return -1;
05186 }
05187 
05188 /* Iterate through the blocks of a trace frame, looking for a 'V'
05189    block with a matching tsv number.  */
05190 
05191 static int
05192 tfile_get_trace_state_variable_value (int tsvnum, LONGEST *val)
05193 {
05194   int pos;
05195   int found = 0;
05196 
05197   /* Iterate over blocks in current frame and find the last 'V'
05198      block in which tsv number is TSVNUM.  In one trace frame, there
05199      may be multiple 'V' blocks created for a given trace variable,
05200      and the last matched 'V' block contains the updated value.  */
05201   pos = 0;
05202   while ((pos = traceframe_find_block_type ('V', pos)) >= 0)
05203     {
05204       int vnum;
05205 
05206       tfile_read ((gdb_byte *) &vnum, 4);
05207       vnum = (int) extract_signed_integer ((gdb_byte *) &vnum, 4,
05208                                            gdbarch_byte_order
05209                                            (target_gdbarch ()));
05210       if (tsvnum == vnum)
05211         {
05212           tfile_read ((gdb_byte *) val, 8);
05213           *val = extract_signed_integer ((gdb_byte *) val, 8,
05214                                          gdbarch_byte_order
05215                                          (target_gdbarch ()));
05216           found = 1;
05217         }
05218       pos += (4 + 8);
05219     }
05220 
05221   return found;
05222 }
05223 
05224 static int
05225 tfile_has_all_memory (struct target_ops *ops)
05226 {
05227   return 1;
05228 }
05229 
05230 static int
05231 tfile_has_memory (struct target_ops *ops)
05232 {
05233   return 1;
05234 }
05235 
05236 static int
05237 tfile_has_stack (struct target_ops *ops)
05238 {
05239   return traceframe_number != -1;
05240 }
05241 
05242 static int
05243 tfile_has_registers (struct target_ops *ops)
05244 {
05245   return traceframe_number != -1;
05246 }
05247 
05248 /* Callback for traceframe_walk_blocks.  Builds a traceframe_info
05249    object for the tfile target's current traceframe.  */
05250 
05251 static int
05252 build_traceframe_info (char blocktype, void *data)
05253 {
05254   struct traceframe_info *info = data;
05255 
05256   switch (blocktype)
05257     {
05258     case 'M':
05259       {
05260         struct mem_range *r;
05261         ULONGEST maddr;
05262         unsigned short mlen;
05263 
05264         tfile_read ((gdb_byte *) &maddr, 8);
05265         maddr = extract_unsigned_integer ((gdb_byte *) &maddr, 8,
05266                                           gdbarch_byte_order
05267                                           (target_gdbarch ()));
05268         tfile_read ((gdb_byte *) &mlen, 2);
05269         mlen = (unsigned short)
05270                 extract_unsigned_integer ((gdb_byte *) &mlen,
05271                                           2, gdbarch_byte_order
05272                                           (target_gdbarch ()));
05273 
05274         r = VEC_safe_push (mem_range_s, info->memory, NULL);
05275 
05276         r->start = maddr;
05277         r->length = mlen;
05278         break;
05279       }
05280     case 'V':
05281       {
05282         int vnum;
05283 
05284         tfile_read ((gdb_byte *) &vnum, 4);
05285         VEC_safe_push (int, info->tvars, vnum);
05286       }
05287     case 'R':
05288     case 'S':
05289       {
05290         break;
05291       }
05292     default:
05293       warning (_("Unhandled trace block type (%d) '%c ' "
05294                  "while building trace frame info."),
05295                blocktype, blocktype);
05296       break;
05297     }
05298 
05299   return 0;
05300 }
05301 
05302 static struct traceframe_info *
05303 tfile_traceframe_info (void)
05304 {
05305   struct traceframe_info *info = XCNEW (struct traceframe_info);
05306 
05307   traceframe_walk_blocks (build_traceframe_info, 0, info);
05308   return info;
05309 }
05310 
05311 static void
05312 init_tfile_ops (void)
05313 {
05314   tfile_ops.to_shortname = "tfile";
05315   tfile_ops.to_longname = "Local trace dump file";
05316   tfile_ops.to_doc
05317     = "Use a trace file as a target.  Specify the filename of the trace file.";
05318   tfile_ops.to_open = tfile_open;
05319   tfile_ops.to_close = tfile_close;
05320   tfile_ops.to_fetch_registers = tfile_fetch_registers;
05321   tfile_ops.to_xfer_partial = tfile_xfer_partial;
05322   tfile_ops.to_files_info = tfile_files_info;
05323   tfile_ops.to_get_trace_status = tfile_get_trace_status;
05324   tfile_ops.to_get_tracepoint_status = tfile_get_tracepoint_status;
05325   tfile_ops.to_trace_find = tfile_trace_find;
05326   tfile_ops.to_get_trace_state_variable_value
05327     = tfile_get_trace_state_variable_value;
05328   tfile_ops.to_stratum = process_stratum;
05329   tfile_ops.to_has_all_memory = tfile_has_all_memory;
05330   tfile_ops.to_has_memory = tfile_has_memory;
05331   tfile_ops.to_has_stack = tfile_has_stack;
05332   tfile_ops.to_has_registers = tfile_has_registers;
05333   tfile_ops.to_traceframe_info = tfile_traceframe_info;
05334   tfile_ops.to_magic = OPS_MAGIC;
05335 }
05336 
05337 void
05338 free_current_marker (void *arg)
05339 {
05340   struct static_tracepoint_marker **marker_p = arg;
05341 
05342   if (*marker_p != NULL)
05343     {
05344       release_static_tracepoint_marker (*marker_p);
05345       xfree (*marker_p);
05346     }
05347   else
05348     *marker_p = NULL;
05349 }
05350 
05351 /* Given a line of text defining a static tracepoint marker, parse it
05352    into a "static tracepoint marker" object.  Throws an error is
05353    parsing fails.  If PP is non-null, it points to one past the end of
05354    the parsed marker definition.  */
05355 
05356 void
05357 parse_static_tracepoint_marker_definition (char *line, char **pp,
05358                                            struct static_tracepoint_marker *marker)
05359 {
05360   char *p, *endp;
05361   ULONGEST addr;
05362   int end;
05363 
05364   p = line;
05365   p = unpack_varlen_hex (p, &addr);
05366   p++;  /* skip a colon */
05367 
05368   marker->gdbarch = target_gdbarch ();
05369   marker->address = (CORE_ADDR) addr;
05370 
05371   endp = strchr (p, ':');
05372   if (endp == NULL)
05373     error (_("bad marker definition: %s"), line);
05374 
05375   marker->str_id = xmalloc (endp - p + 1);
05376   end = hex2bin (p, (gdb_byte *) marker->str_id, (endp - p + 1) / 2);
05377   marker->str_id[end] = '\0';
05378 
05379   p += 2 * end;
05380   p++;  /* skip a colon */
05381 
05382   marker->extra = xmalloc (strlen (p) + 1);
05383   end = hex2bin (p, (gdb_byte *) marker->extra, strlen (p) / 2);
05384   marker->extra[end] = '\0';
05385 
05386   if (pp)
05387     *pp = p;
05388 }
05389 
05390 /* Release a static tracepoint marker's contents.  Note that the
05391    object itself isn't released here.  There objects are usually on
05392    the stack.  */
05393 
05394 void
05395 release_static_tracepoint_marker (struct static_tracepoint_marker *marker)
05396 {
05397   xfree (marker->str_id);
05398   marker->str_id = NULL;
05399 }
05400 
05401 /* Print MARKER to gdb_stdout.  */
05402 
05403 static void
05404 print_one_static_tracepoint_marker (int count,
05405                                     struct static_tracepoint_marker *marker)
05406 {
05407   struct command_line *l;
05408   struct symbol *sym;
05409 
05410   char wrap_indent[80];
05411   char extra_field_indent[80];
05412   struct ui_out *uiout = current_uiout;
05413   struct cleanup *bkpt_chain;
05414   VEC(breakpoint_p) *tracepoints;
05415 
05416   struct symtab_and_line sal;
05417 
05418   init_sal (&sal);
05419 
05420   sal.pc = marker->address;
05421 
05422   tracepoints = static_tracepoints_here (marker->address);
05423 
05424   bkpt_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "marker");
05425 
05426   /* A counter field to help readability.  This is not a stable
05427      identifier!  */
05428   ui_out_field_int (uiout, "count", count);
05429 
05430   ui_out_field_string (uiout, "marker-id", marker->str_id);
05431 
05432   ui_out_field_fmt (uiout, "enabled", "%c",
05433                     !VEC_empty (breakpoint_p, tracepoints) ? 'y' : 'n');
05434   ui_out_spaces (uiout, 2);
05435 
05436   strcpy (wrap_indent, "                                   ");
05437 
05438   if (gdbarch_addr_bit (marker->gdbarch) <= 32)
05439     strcat (wrap_indent, "           ");
05440   else
05441     strcat (wrap_indent, "                   ");
05442 
05443   strcpy (extra_field_indent, "         ");
05444 
05445   ui_out_field_core_addr (uiout, "addr", marker->gdbarch, marker->address);
05446 
05447   sal = find_pc_line (marker->address, 0);
05448   sym = find_pc_sect_function (marker->address, NULL);
05449   if (sym)
05450     {
05451       ui_out_text (uiout, "in ");
05452       ui_out_field_string (uiout, "func",
05453                            SYMBOL_PRINT_NAME (sym));
05454       ui_out_wrap_hint (uiout, wrap_indent);
05455       ui_out_text (uiout, " at ");
05456     }
05457   else
05458     ui_out_field_skip (uiout, "func");
05459 
05460   if (sal.symtab != NULL)
05461     {
05462       ui_out_field_string (uiout, "file",
05463                            symtab_to_filename_for_display (sal.symtab));
05464       ui_out_text (uiout, ":");
05465 
05466       if (ui_out_is_mi_like_p (uiout))
05467         {
05468           const char *fullname = symtab_to_fullname (sal.symtab);
05469 
05470           ui_out_field_string (uiout, "fullname", fullname);
05471         }
05472       else
05473         ui_out_field_skip (uiout, "fullname");
05474 
05475       ui_out_field_int (uiout, "line", sal.line);
05476     }
05477   else
05478     {
05479       ui_out_field_skip (uiout, "fullname");
05480       ui_out_field_skip (uiout, "line");
05481     }
05482 
05483   ui_out_text (uiout, "\n");
05484   ui_out_text (uiout, extra_field_indent);
05485   ui_out_text (uiout, _("Data: \""));
05486   ui_out_field_string (uiout, "extra-data", marker->extra);
05487   ui_out_text (uiout, "\"\n");
05488 
05489   if (!VEC_empty (breakpoint_p, tracepoints))
05490     {
05491       struct cleanup *cleanup_chain;
05492       int ix;
05493       struct breakpoint *b;
05494 
05495       cleanup_chain = make_cleanup_ui_out_tuple_begin_end (uiout,
05496                                                            "tracepoints-at");
05497 
05498       ui_out_text (uiout, extra_field_indent);
05499       ui_out_text (uiout, _("Probed by static tracepoints: "));
05500       for (ix = 0; VEC_iterate(breakpoint_p, tracepoints, ix, b); ix++)
05501         {
05502           if (ix > 0)
05503             ui_out_text (uiout, ", ");
05504           ui_out_text (uiout, "#");
05505           ui_out_field_int (uiout, "tracepoint-id", b->number);
05506         }
05507 
05508       do_cleanups (cleanup_chain);
05509 
05510       if (ui_out_is_mi_like_p (uiout))
05511         ui_out_field_int (uiout, "number-of-tracepoints",
05512                           VEC_length(breakpoint_p, tracepoints));
05513       else
05514         ui_out_text (uiout, "\n");
05515     }
05516   VEC_free (breakpoint_p, tracepoints);
05517 
05518   do_cleanups (bkpt_chain);
05519 }
05520 
05521 static void
05522 info_static_tracepoint_markers_command (char *arg, int from_tty)
05523 {
05524   VEC(static_tracepoint_marker_p) *markers;
05525   struct cleanup *old_chain;
05526   struct static_tracepoint_marker *marker;
05527   struct ui_out *uiout = current_uiout;
05528   int i;
05529 
05530   /* We don't have to check target_can_use_agent and agent's capability on
05531      static tracepoint here, in order to be compatible with older GDBserver.
05532      We don't check USE_AGENT is true or not, because static tracepoints
05533      don't work without in-process agent, so we don't bother users to type
05534      `set agent on' when to use static tracepoint.  */
05535 
05536   old_chain
05537     = make_cleanup_ui_out_table_begin_end (uiout, 5, -1,
05538                                            "StaticTracepointMarkersTable");
05539 
05540   ui_out_table_header (uiout, 7, ui_left, "counter", "Cnt");
05541 
05542   ui_out_table_header (uiout, 40, ui_left, "marker-id", "ID");
05543 
05544   ui_out_table_header (uiout, 3, ui_left, "enabled", "Enb");
05545   if (gdbarch_addr_bit (target_gdbarch ()) <= 32)
05546     ui_out_table_header (uiout, 10, ui_left, "addr", "Address");
05547   else
05548     ui_out_table_header (uiout, 18, ui_left, "addr", "Address");
05549   ui_out_table_header (uiout, 40, ui_noalign, "what", "What");
05550 
05551   ui_out_table_body (uiout);
05552 
05553   markers = target_static_tracepoint_markers_by_strid (NULL);
05554   make_cleanup (VEC_cleanup (static_tracepoint_marker_p), &markers);
05555 
05556   for (i = 0;
05557        VEC_iterate (static_tracepoint_marker_p,
05558                     markers, i, marker);
05559        i++)
05560     {
05561       print_one_static_tracepoint_marker (i + 1, marker);
05562       release_static_tracepoint_marker (marker);
05563     }
05564 
05565   do_cleanups (old_chain);
05566 }
05567 
05568 /* The $_sdata convenience variable is a bit special.  We don't know
05569    for sure type of the value until we actually have a chance to fetch
05570    the data --- the size of the object depends on what has been
05571    collected.  We solve this by making $_sdata be an internalvar that
05572    creates a new value on access.  */
05573 
05574 /* Return a new value with the correct type for the sdata object of
05575    the current trace frame.  Return a void value if there's no object
05576    available.  */
05577 
05578 static struct value *
05579 sdata_make_value (struct gdbarch *gdbarch, struct internalvar *var,
05580                   void *ignore)
05581 {
05582   LONGEST size;
05583   gdb_byte *buf;
05584 
05585   /* We need to read the whole object before we know its size.  */
05586   size = target_read_alloc (&current_target,
05587                             TARGET_OBJECT_STATIC_TRACE_DATA,
05588                             NULL, &buf);
05589   if (size >= 0)
05590     {
05591       struct value *v;
05592       struct type *type;
05593 
05594       type = init_vector_type (builtin_type (gdbarch)->builtin_true_char,
05595                                size);
05596       v = allocate_value (type);
05597       memcpy (value_contents_raw (v), buf, size);
05598       xfree (buf);
05599       return v;
05600     }
05601   else
05602     return allocate_value (builtin_type (gdbarch)->builtin_void);
05603 }
05604 
05605 #if !defined(HAVE_LIBEXPAT)
05606 
05607 struct traceframe_info *
05608 parse_traceframe_info (const char *tframe_info)
05609 {
05610   static int have_warned;
05611 
05612   if (!have_warned)
05613     {
05614       have_warned = 1;
05615       warning (_("Can not parse XML trace frame info; XML support "
05616                  "was disabled at compile time"));
05617     }
05618 
05619   return NULL;
05620 }
05621 
05622 #else /* HAVE_LIBEXPAT */
05623 
05624 #include "xml-support.h"
05625 
05626 /* Handle the start of a <memory> element.  */
05627 
05628 static void
05629 traceframe_info_start_memory (struct gdb_xml_parser *parser,
05630                               const struct gdb_xml_element *element,
05631                               void *user_data, VEC(gdb_xml_value_s) *attributes)
05632 {
05633   struct traceframe_info *info = user_data;
05634   struct mem_range *r = VEC_safe_push (mem_range_s, info->memory, NULL);
05635   ULONGEST *start_p, *length_p;
05636 
05637   start_p = xml_find_attribute (attributes, "start")->value;
05638   length_p = xml_find_attribute (attributes, "length")->value;
05639 
05640   r->start = *start_p;
05641   r->length = *length_p;
05642 }
05643 
05644 /* Handle the start of a <tvar> element.  */
05645 
05646 static void
05647 traceframe_info_start_tvar (struct gdb_xml_parser *parser,
05648                              const struct gdb_xml_element *element,
05649                              void *user_data,
05650                              VEC(gdb_xml_value_s) *attributes)
05651 {
05652   struct traceframe_info *info = user_data;
05653   const char *id_attrib = xml_find_attribute (attributes, "id")->value;
05654   int id = gdb_xml_parse_ulongest (parser, id_attrib);
05655 
05656   VEC_safe_push (int, info->tvars, id);
05657 }
05658 
05659 /* Discard the constructed trace frame info (if an error occurs).  */
05660 
05661 static void
05662 free_result (void *p)
05663 {
05664   struct traceframe_info *result = p;
05665 
05666   free_traceframe_info (result);
05667 }
05668 
05669 /* The allowed elements and attributes for an XML memory map.  */
05670 
05671 static const struct gdb_xml_attribute memory_attributes[] = {
05672   { "start", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
05673   { "length", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
05674   { NULL, GDB_XML_AF_NONE, NULL, NULL }
05675 };
05676 
05677 static const struct gdb_xml_attribute tvar_attributes[] = {
05678   { "id", GDB_XML_AF_NONE, NULL, NULL },
05679   { NULL, GDB_XML_AF_NONE, NULL, NULL }
05680 };
05681 
05682 static const struct gdb_xml_element traceframe_info_children[] = {
05683   { "memory", memory_attributes, NULL,
05684     GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
05685     traceframe_info_start_memory, NULL },
05686   { "tvar", tvar_attributes, NULL,
05687     GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
05688     traceframe_info_start_tvar, NULL },
05689   { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
05690 };
05691 
05692 static const struct gdb_xml_element traceframe_info_elements[] = {
05693   { "traceframe-info", NULL, traceframe_info_children, GDB_XML_EF_NONE,
05694     NULL, NULL },
05695   { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
05696 };
05697 
05698 /* Parse a traceframe-info XML document.  */
05699 
05700 struct traceframe_info *
05701 parse_traceframe_info (const char *tframe_info)
05702 {
05703   struct traceframe_info *result;
05704   struct cleanup *back_to;
05705 
05706   result = XCNEW (struct traceframe_info);
05707   back_to = make_cleanup (free_result, result);
05708 
05709   if (gdb_xml_parse_quick (_("trace frame info"),
05710                            "traceframe-info.dtd", traceframe_info_elements,
05711                            tframe_info, result) == 0)
05712     {
05713       /* Parsed successfully, keep the result.  */
05714       discard_cleanups (back_to);
05715 
05716       return result;
05717     }
05718 
05719   do_cleanups (back_to);
05720   return NULL;
05721 }
05722 
05723 #endif /* HAVE_LIBEXPAT */
05724 
05725 /* Returns the traceframe_info object for the current traceframe.
05726    This is where we avoid re-fetching the object from the target if we
05727    already have it cached.  */
05728 
05729 struct traceframe_info *
05730 get_traceframe_info (void)
05731 {
05732   if (traceframe_info == NULL)
05733     traceframe_info = target_traceframe_info ();
05734 
05735   return traceframe_info;
05736 }
05737 
05738 /* If the target supports the query, return in RESULT the set of
05739    collected memory in the current traceframe, found within the LEN
05740    bytes range starting at MEMADDR.  Returns true if the target
05741    supports the query, otherwise returns false, and RESULT is left
05742    undefined.  */
05743 
05744 int
05745 traceframe_available_memory (VEC(mem_range_s) **result,
05746                              CORE_ADDR memaddr, ULONGEST len)
05747 {
05748   struct traceframe_info *info = get_traceframe_info ();
05749 
05750   if (info != NULL)
05751     {
05752       struct mem_range *r;
05753       int i;
05754 
05755       *result = NULL;
05756 
05757       for (i = 0; VEC_iterate (mem_range_s, info->memory, i, r); i++)
05758         if (mem_ranges_overlap (r->start, r->length, memaddr, len))
05759           {
05760             ULONGEST lo1, hi1, lo2, hi2;
05761             struct mem_range *nr;
05762 
05763             lo1 = memaddr;
05764             hi1 = memaddr + len;
05765 
05766             lo2 = r->start;
05767             hi2 = r->start + r->length;
05768 
05769             nr = VEC_safe_push (mem_range_s, *result, NULL);
05770 
05771             nr->start = max (lo1, lo2);
05772             nr->length = min (hi1, hi2) - nr->start;
05773           }
05774 
05775       normalize_mem_ranges (*result);
05776       return 1;
05777     }
05778 
05779   return 0;
05780 }
05781 
05782 /* Implementation of `sdata' variable.  */
05783 
05784 static const struct internalvar_funcs sdata_funcs =
05785 {
05786   sdata_make_value,
05787   NULL,
05788   NULL
05789 };
05790 
05791 /* module initialization */
05792 void
05793 _initialize_tracepoint (void)
05794 {
05795   struct cmd_list_element *c;
05796 
05797   /* Explicitly create without lookup, since that tries to create a
05798      value with a void typed value, and when we get here, gdbarch
05799      isn't initialized yet.  At this point, we're quite sure there
05800      isn't another convenience variable of the same name.  */
05801   create_internalvar_type_lazy ("_sdata", &sdata_funcs, NULL);
05802 
05803   traceframe_number = -1;
05804   tracepoint_number = -1;
05805 
05806   add_info ("scope", scope_info,
05807             _("List the variables local to a scope"));
05808 
05809   add_cmd ("tracepoints", class_trace, NULL,
05810            _("Tracing of program execution without stopping the program."),
05811            &cmdlist);
05812 
05813   add_com ("tdump", class_trace, trace_dump_command,
05814            _("Print everything collected at the current tracepoint."));
05815 
05816   add_com ("tsave", class_trace, trace_save_command, _("\
05817 Save the trace data to a file.\n\
05818 Use the '-ctf' option to save the data to CTF format.\n\
05819 Use the '-r' option to direct the target to save directly to the file,\n\
05820 using its own filesystem."));
05821 
05822   c = add_com ("tvariable", class_trace, trace_variable_command,_("\
05823 Define a trace state variable.\n\
05824 Argument is a $-prefixed name, optionally followed\n\
05825 by '=' and an expression that sets the initial value\n\
05826 at the start of tracing."));
05827   set_cmd_completer (c, expression_completer);
05828 
05829   add_cmd ("tvariable", class_trace, delete_trace_variable_command, _("\
05830 Delete one or more trace state variables.\n\
05831 Arguments are the names of the variables to delete.\n\
05832 If no arguments are supplied, delete all variables."), &deletelist);
05833   /* FIXME add a trace variable completer.  */
05834 
05835   add_info ("tvariables", tvariables_info, _("\
05836 Status of trace state variables and their values.\n\
05837 "));
05838 
05839   add_info ("static-tracepoint-markers",
05840             info_static_tracepoint_markers_command, _("\
05841 List target static tracepoints markers.\n\
05842 "));
05843 
05844   add_prefix_cmd ("tfind", class_trace, trace_find_command, _("\
05845 Select a trace frame;\n\
05846 No argument means forward by one frame; '-' means backward by one frame."),
05847                   &tfindlist, "tfind ", 1, &cmdlist);
05848 
05849   add_cmd ("outside", class_trace, trace_find_outside_command, _("\
05850 Select a trace frame whose PC is outside the given range (exclusive).\n\
05851 Usage: tfind outside addr1, addr2"),
05852            &tfindlist);
05853 
05854   add_cmd ("range", class_trace, trace_find_range_command, _("\
05855 Select a trace frame whose PC is in the given range (inclusive).\n\
05856 Usage: tfind range addr1,addr2"),
05857            &tfindlist);
05858 
05859   add_cmd ("line", class_trace, trace_find_line_command, _("\
05860 Select a trace frame by source line.\n\
05861 Argument can be a line number (with optional source file),\n\
05862 a function name, or '*' followed by an address.\n\
05863 Default argument is 'the next source line that was traced'."),
05864            &tfindlist);
05865 
05866   add_cmd ("tracepoint", class_trace, trace_find_tracepoint_command, _("\
05867 Select a trace frame by tracepoint number.\n\
05868 Default is the tracepoint for the current trace frame."),
05869            &tfindlist);
05870 
05871   add_cmd ("pc", class_trace, trace_find_pc_command, _("\
05872 Select a trace frame by PC.\n\
05873 Default is the current PC, or the PC of the current trace frame."),
05874            &tfindlist);
05875 
05876   add_cmd ("end", class_trace, trace_find_end_command, _("\
05877 De-select any trace frame and resume 'live' debugging."),
05878            &tfindlist);
05879 
05880   add_alias_cmd ("none", "end", class_trace, 0, &tfindlist);
05881 
05882   add_cmd ("start", class_trace, trace_find_start_command,
05883            _("Select the first trace frame in the trace buffer."),
05884            &tfindlist);
05885 
05886   add_com ("tstatus", class_trace, trace_status_command,
05887            _("Display the status of the current trace data collection."));
05888 
05889   add_com ("tstop", class_trace, trace_stop_command, _("\
05890 Stop trace data collection.\n\
05891 Usage: tstop [ <notes> ... ]\n\
05892 Any arguments supplied are recorded with the trace as a stop reason and\n\
05893 reported by tstatus (if the target supports trace notes)."));
05894 
05895   add_com ("tstart", class_trace, trace_start_command, _("\
05896 Start trace data collection.\n\
05897 Usage: tstart [ <notes> ... ]\n\
05898 Any arguments supplied are recorded with the trace as a note and\n\
05899 reported by tstatus (if the target supports trace notes)."));
05900 
05901   add_com ("end", class_trace, end_actions_pseudocommand, _("\
05902 Ends a list of commands or actions.\n\
05903 Several GDB commands allow you to enter a list of commands or actions.\n\
05904 Entering \"end\" on a line by itself is the normal way to terminate\n\
05905 such a list.\n\n\
05906 Note: the \"end\" command cannot be used at the gdb prompt."));
05907 
05908   add_com ("while-stepping", class_trace, while_stepping_pseudocommand, _("\
05909 Specify single-stepping behavior at a tracepoint.\n\
05910 Argument is number of instructions to trace in single-step mode\n\
05911 following the tracepoint.  This command is normally followed by\n\
05912 one or more \"collect\" commands, to specify what to collect\n\
05913 while single-stepping.\n\n\
05914 Note: this command can only be used in a tracepoint \"actions\" list."));
05915 
05916   add_com_alias ("ws", "while-stepping", class_alias, 0);
05917   add_com_alias ("stepping", "while-stepping", class_alias, 0);
05918 
05919   add_com ("collect", class_trace, collect_pseudocommand, _("\
05920 Specify one or more data items to be collected at a tracepoint.\n\
05921 Accepts a comma-separated list of (one or more) expressions.  GDB will\n\
05922 collect all data (variables, registers) referenced by that expression.\n\
05923 Also accepts the following special arguments:\n\
05924     $regs   -- all registers.\n\
05925     $args   -- all function arguments.\n\
05926     $locals -- all variables local to the block/function scope.\n\
05927     $_sdata -- static tracepoint data (ignored for non-static tracepoints).\n\
05928 Note: this command can only be used in a tracepoint \"actions\" list."));
05929 
05930   add_com ("teval", class_trace, teval_pseudocommand, _("\
05931 Specify one or more expressions to be evaluated at a tracepoint.\n\
05932 Accepts a comma-separated list of (one or more) expressions.\n\
05933 The result of each evaluation will be discarded.\n\
05934 Note: this command can only be used in a tracepoint \"actions\" list."));
05935 
05936   add_com ("actions", class_trace, trace_actions_command, _("\
05937 Specify the actions to be taken at a tracepoint.\n\
05938 Tracepoint actions may include collecting of specified data,\n\
05939 single-stepping, or enabling/disabling other tracepoints,\n\
05940 depending on target's capabilities."));
05941 
05942   default_collect = xstrdup ("");
05943   add_setshow_string_cmd ("default-collect", class_trace,
05944                           &default_collect, _("\
05945 Set the list of expressions to collect by default"), _("\
05946 Show the list of expressions to collect by default"), NULL,
05947                           NULL, NULL,
05948                           &setlist, &showlist);
05949 
05950   add_setshow_boolean_cmd ("disconnected-tracing", no_class,
05951                            &disconnected_tracing, _("\
05952 Set whether tracing continues after GDB disconnects."), _("\
05953 Show whether tracing continues after GDB disconnects."), _("\
05954 Use this to continue a tracing run even if GDB disconnects\n\
05955 or detaches from the target.  You can reconnect later and look at\n\
05956 trace data collected in the meantime."),
05957                            set_disconnected_tracing,
05958                            NULL,
05959                            &setlist,
05960                            &showlist);
05961 
05962   add_setshow_boolean_cmd ("circular-trace-buffer", no_class,
05963                            &circular_trace_buffer, _("\
05964 Set target's use of circular trace buffer."), _("\
05965 Show target's use of circular trace buffer."), _("\
05966 Use this to make the trace buffer into a circular buffer,\n\
05967 which will discard traceframes (oldest first) instead of filling\n\
05968 up and stopping the trace run."),
05969                            set_circular_trace_buffer,
05970                            NULL,
05971                            &setlist,
05972                            &showlist);
05973 
05974   add_setshow_zuinteger_unlimited_cmd ("trace-buffer-size", no_class,
05975                                        &trace_buffer_size, _("\
05976 Set requested size of trace buffer."), _("\
05977 Show requested size of trace buffer."), _("\
05978 Use this to choose a size for the trace buffer.  Some targets\n\
05979 may have fixed or limited buffer sizes.  Specifying \"unlimited\" or -1\n\
05980 disables any attempt to set the buffer size and lets the target choose."),
05981                                        set_trace_buffer_size, NULL,
05982                                        &setlist, &showlist);
05983 
05984   add_setshow_string_cmd ("trace-user", class_trace,
05985                           &trace_user, _("\
05986 Set the user name to use for current and future trace runs"), _("\
05987 Show the user name to use for current and future trace runs"), NULL,
05988                           set_trace_user, NULL,
05989                           &setlist, &showlist);
05990 
05991   add_setshow_string_cmd ("trace-notes", class_trace,
05992                           &trace_notes, _("\
05993 Set notes string to use for current and future trace runs"), _("\
05994 Show the notes string to use for current and future trace runs"), NULL,
05995                           set_trace_notes, NULL,
05996                           &setlist, &showlist);
05997 
05998   add_setshow_string_cmd ("trace-stop-notes", class_trace,
05999                           &trace_stop_notes, _("\
06000 Set notes string to use for future tstop commands"), _("\
06001 Show the notes string to use for future tstop commands"), NULL,
06002                           set_trace_stop_notes, NULL,
06003                           &setlist, &showlist);
06004 
06005   init_tfile_ops ();
06006 
06007   add_target_with_completer (&tfile_ops, filename_completer);
06008 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines