OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [gdb/] [tracepoint.c] - Blame information for rev 853

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.