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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [gdb/] [tracepoint.c] - Blame information for rev 321

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

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

powered by: WebSVN 2.1.0

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