configure: check for libipt
[deliverable/binutils-gdb.git] / gdb / record-btrace.c
CommitLineData
afedecd3
MM
1/* Branch trace support for GDB, the GNU debugger.
2
32d0add0 3 Copyright (C) 2013-2015 Free Software Foundation, Inc.
afedecd3
MM
4
5 Contributed by Intel Corp. <markus.t.metzger@intel.com>
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21
22#include "defs.h"
23#include "record.h"
24#include "gdbthread.h"
25#include "target.h"
26#include "gdbcmd.h"
27#include "disasm.h"
28#include "observer.h"
afedecd3
MM
29#include "cli/cli-utils.h"
30#include "source.h"
31#include "ui-out.h"
32#include "symtab.h"
33#include "filenames.h"
1f3ef581 34#include "regcache.h"
cecac1ab 35#include "frame-unwind.h"
0b722aec 36#include "hashtab.h"
45741a9c 37#include "infrun.h"
70ad5bff
MM
38#include "event-loop.h"
39#include "inf-loop.h"
afedecd3
MM
40
41/* The target_ops of record-btrace. */
42static struct target_ops record_btrace_ops;
43
44/* A new thread observer enabling branch tracing for the new thread. */
45static struct observer *record_btrace_thread_observer;
46
67b5c0c1
MM
47/* Memory access types used in set/show record btrace replay-memory-access. */
48static const char replay_memory_access_read_only[] = "read-only";
49static const char replay_memory_access_read_write[] = "read-write";
50static const char *const replay_memory_access_types[] =
51{
52 replay_memory_access_read_only,
53 replay_memory_access_read_write,
54 NULL
55};
56
57/* The currently allowed replay memory access type. */
58static const char *replay_memory_access = replay_memory_access_read_only;
59
60/* Command lists for "set/show record btrace". */
61static struct cmd_list_element *set_record_btrace_cmdlist;
62static struct cmd_list_element *show_record_btrace_cmdlist;
633785ff 63
70ad5bff
MM
64/* The execution direction of the last resume we got. See record-full.c. */
65static enum exec_direction_kind record_btrace_resume_exec_dir = EXEC_FORWARD;
66
67/* The async event handler for reverse/replay execution. */
68static struct async_event_handler *record_btrace_async_inferior_event_handler;
69
aef92902
MM
70/* A flag indicating that we are currently generating a core file. */
71static int record_btrace_generating_corefile;
72
f4abbc16
MM
73/* The current branch trace configuration. */
74static struct btrace_config record_btrace_conf;
75
76/* Command list for "record btrace". */
77static struct cmd_list_element *record_btrace_cmdlist;
78
d33501a5
MM
79/* Command lists for "set/show record btrace bts". */
80static struct cmd_list_element *set_record_btrace_bts_cmdlist;
81static struct cmd_list_element *show_record_btrace_bts_cmdlist;
82
afedecd3
MM
83/* Print a record-btrace debug message. Use do ... while (0) to avoid
84 ambiguities when used in if statements. */
85
86#define DEBUG(msg, args...) \
87 do \
88 { \
89 if (record_debug != 0) \
90 fprintf_unfiltered (gdb_stdlog, \
91 "[record-btrace] " msg "\n", ##args); \
92 } \
93 while (0)
94
95
96/* Update the branch trace for the current thread and return a pointer to its
066ce621 97 thread_info.
afedecd3
MM
98
99 Throws an error if there is no thread or no trace. This function never
100 returns NULL. */
101
066ce621
MM
102static struct thread_info *
103require_btrace_thread (void)
afedecd3
MM
104{
105 struct thread_info *tp;
afedecd3
MM
106
107 DEBUG ("require");
108
109 tp = find_thread_ptid (inferior_ptid);
110 if (tp == NULL)
111 error (_("No thread."));
112
113 btrace_fetch (tp);
114
6e07b1d2 115 if (btrace_is_empty (tp))
afedecd3
MM
116 error (_("No trace."));
117
066ce621
MM
118 return tp;
119}
120
121/* Update the branch trace for the current thread and return a pointer to its
122 branch trace information struct.
123
124 Throws an error if there is no thread or no trace. This function never
125 returns NULL. */
126
127static struct btrace_thread_info *
128require_btrace (void)
129{
130 struct thread_info *tp;
131
132 tp = require_btrace_thread ();
133
134 return &tp->btrace;
afedecd3
MM
135}
136
137/* Enable branch tracing for one thread. Warn on errors. */
138
139static void
140record_btrace_enable_warn (struct thread_info *tp)
141{
492d29ea
PA
142 TRY
143 {
144 btrace_enable (tp, &record_btrace_conf);
145 }
146 CATCH (error, RETURN_MASK_ERROR)
147 {
148 warning ("%s", error.message);
149 }
150 END_CATCH
afedecd3
MM
151}
152
153/* Callback function to disable branch tracing for one thread. */
154
155static void
156record_btrace_disable_callback (void *arg)
157{
158 struct thread_info *tp;
159
160 tp = arg;
161
162 btrace_disable (tp);
163}
164
165/* Enable automatic tracing of new threads. */
166
167static void
168record_btrace_auto_enable (void)
169{
170 DEBUG ("attach thread observer");
171
172 record_btrace_thread_observer
173 = observer_attach_new_thread (record_btrace_enable_warn);
174}
175
176/* Disable automatic tracing of new threads. */
177
178static void
179record_btrace_auto_disable (void)
180{
181 /* The observer may have been detached, already. */
182 if (record_btrace_thread_observer == NULL)
183 return;
184
185 DEBUG ("detach thread observer");
186
187 observer_detach_new_thread (record_btrace_thread_observer);
188 record_btrace_thread_observer = NULL;
189}
190
70ad5bff
MM
191/* The record-btrace async event handler function. */
192
193static void
194record_btrace_handle_async_inferior_event (gdb_client_data data)
195{
196 inferior_event_handler (INF_REG_EVENT, NULL);
197}
198
afedecd3
MM
199/* The to_open method of target record-btrace. */
200
201static void
014f9477 202record_btrace_open (const char *args, int from_tty)
afedecd3
MM
203{
204 struct cleanup *disable_chain;
205 struct thread_info *tp;
206
207 DEBUG ("open");
208
8213266a 209 record_preopen ();
afedecd3
MM
210
211 if (!target_has_execution)
212 error (_("The program is not being run."));
213
52834460
MM
214 if (non_stop)
215 error (_("Record btrace can't debug inferior in non-stop mode."));
216
afedecd3
MM
217 gdb_assert (record_btrace_thread_observer == NULL);
218
219 disable_chain = make_cleanup (null_cleanup, NULL);
034f788c 220 ALL_NON_EXITED_THREADS (tp)
afedecd3
MM
221 if (args == NULL || *args == 0 || number_is_in_list (args, tp->num))
222 {
f4abbc16 223 btrace_enable (tp, &record_btrace_conf);
afedecd3
MM
224
225 make_cleanup (record_btrace_disable_callback, tp);
226 }
227
228 record_btrace_auto_enable ();
229
230 push_target (&record_btrace_ops);
231
70ad5bff
MM
232 record_btrace_async_inferior_event_handler
233 = create_async_event_handler (record_btrace_handle_async_inferior_event,
234 NULL);
aef92902 235 record_btrace_generating_corefile = 0;
70ad5bff 236
afedecd3
MM
237 observer_notify_record_changed (current_inferior (), 1);
238
239 discard_cleanups (disable_chain);
240}
241
242/* The to_stop_recording method of target record-btrace. */
243
244static void
c6cd7c02 245record_btrace_stop_recording (struct target_ops *self)
afedecd3
MM
246{
247 struct thread_info *tp;
248
249 DEBUG ("stop recording");
250
251 record_btrace_auto_disable ();
252
034f788c 253 ALL_NON_EXITED_THREADS (tp)
afedecd3
MM
254 if (tp->btrace.target != NULL)
255 btrace_disable (tp);
256}
257
258/* The to_close method of target record-btrace. */
259
260static void
de90e03d 261record_btrace_close (struct target_ops *self)
afedecd3 262{
568e808b
MM
263 struct thread_info *tp;
264
70ad5bff
MM
265 if (record_btrace_async_inferior_event_handler != NULL)
266 delete_async_event_handler (&record_btrace_async_inferior_event_handler);
267
99c819ee
MM
268 /* Make sure automatic recording gets disabled even if we did not stop
269 recording before closing the record-btrace target. */
270 record_btrace_auto_disable ();
271
568e808b
MM
272 /* We should have already stopped recording.
273 Tear down btrace in case we have not. */
034f788c 274 ALL_NON_EXITED_THREADS (tp)
568e808b 275 btrace_teardown (tp);
afedecd3
MM
276}
277
b7d2e916
PA
278/* The to_async method of target record-btrace. */
279
280static void
6a3753b3 281record_btrace_async (struct target_ops *ops, int enable)
b7d2e916 282{
6a3753b3 283 if (enable)
b7d2e916
PA
284 mark_async_event_handler (record_btrace_async_inferior_event_handler);
285 else
286 clear_async_event_handler (record_btrace_async_inferior_event_handler);
287
6a3753b3 288 ops->beneath->to_async (ops->beneath, enable);
b7d2e916
PA
289}
290
d33501a5
MM
291/* Adjusts the size and returns a human readable size suffix. */
292
293static const char *
294record_btrace_adjust_size (unsigned int *size)
295{
296 unsigned int sz;
297
298 sz = *size;
299
300 if ((sz & ((1u << 30) - 1)) == 0)
301 {
302 *size = sz >> 30;
303 return "GB";
304 }
305 else if ((sz & ((1u << 20) - 1)) == 0)
306 {
307 *size = sz >> 20;
308 return "MB";
309 }
310 else if ((sz & ((1u << 10) - 1)) == 0)
311 {
312 *size = sz >> 10;
313 return "kB";
314 }
315 else
316 return "";
317}
318
319/* Print a BTS configuration. */
320
321static void
322record_btrace_print_bts_conf (const struct btrace_config_bts *conf)
323{
324 const char *suffix;
325 unsigned int size;
326
327 size = conf->size;
328 if (size > 0)
329 {
330 suffix = record_btrace_adjust_size (&size);
331 printf_unfiltered (_("Buffer size: %u%s.\n"), size, suffix);
332 }
333}
334
335/* Print a branch tracing configuration. */
336
337static void
338record_btrace_print_conf (const struct btrace_config *conf)
339{
340 printf_unfiltered (_("Recording format: %s.\n"),
341 btrace_format_string (conf->format));
342
343 switch (conf->format)
344 {
345 case BTRACE_FORMAT_NONE:
346 return;
347
348 case BTRACE_FORMAT_BTS:
349 record_btrace_print_bts_conf (&conf->bts);
350 return;
351 }
352
353 internal_error (__FILE__, __LINE__, _("Unkown branch trace format."));
354}
355
afedecd3
MM
356/* The to_info_record method of target record-btrace. */
357
358static void
630d6a4a 359record_btrace_info (struct target_ops *self)
afedecd3
MM
360{
361 struct btrace_thread_info *btinfo;
f4abbc16 362 const struct btrace_config *conf;
afedecd3 363 struct thread_info *tp;
31fd9caa 364 unsigned int insns, calls, gaps;
afedecd3
MM
365
366 DEBUG ("info");
367
368 tp = find_thread_ptid (inferior_ptid);
369 if (tp == NULL)
370 error (_("No thread."));
371
f4abbc16
MM
372 btinfo = &tp->btrace;
373
374 conf = btrace_conf (btinfo);
375 if (conf != NULL)
d33501a5 376 record_btrace_print_conf (conf);
f4abbc16 377
afedecd3
MM
378 btrace_fetch (tp);
379
23a7fe75
MM
380 insns = 0;
381 calls = 0;
31fd9caa 382 gaps = 0;
23a7fe75 383
6e07b1d2 384 if (!btrace_is_empty (tp))
23a7fe75
MM
385 {
386 struct btrace_call_iterator call;
387 struct btrace_insn_iterator insn;
388
389 btrace_call_end (&call, btinfo);
390 btrace_call_prev (&call, 1);
5de9129b 391 calls = btrace_call_number (&call);
23a7fe75
MM
392
393 btrace_insn_end (&insn, btinfo);
31fd9caa 394
5de9129b 395 insns = btrace_insn_number (&insn);
31fd9caa
MM
396 if (insns != 0)
397 {
398 /* The last instruction does not really belong to the trace. */
399 insns -= 1;
400 }
401 else
402 {
403 unsigned int steps;
404
405 /* Skip gaps at the end. */
406 do
407 {
408 steps = btrace_insn_prev (&insn, 1);
409 if (steps == 0)
410 break;
411
412 insns = btrace_insn_number (&insn);
413 }
414 while (insns == 0);
415 }
416
417 gaps = btinfo->ngaps;
23a7fe75 418 }
afedecd3 419
31fd9caa
MM
420 printf_unfiltered (_("Recorded %u instructions in %u functions (%u gaps) "
421 "for thread %d (%s).\n"), insns, calls, gaps,
422 tp->num, target_pid_to_str (tp->ptid));
07bbe694
MM
423
424 if (btrace_is_replaying (tp))
425 printf_unfiltered (_("Replay in progress. At instruction %u.\n"),
426 btrace_insn_number (btinfo->replay));
afedecd3
MM
427}
428
31fd9caa
MM
429/* Print a decode error. */
430
431static void
432btrace_ui_out_decode_error (struct ui_out *uiout, int errcode,
433 enum btrace_format format)
434{
435 const char *errstr;
436 int is_error;
437
438 errstr = _("unknown");
439 is_error = 1;
440
441 switch (format)
442 {
443 default:
444 break;
445
446 case BTRACE_FORMAT_BTS:
447 switch (errcode)
448 {
449 default:
450 break;
451
452 case BDE_BTS_OVERFLOW:
453 errstr = _("instruction overflow");
454 break;
455
456 case BDE_BTS_INSN_SIZE:
457 errstr = _("unknown instruction");
458 break;
459 }
460 break;
461 }
462
463 ui_out_text (uiout, _("["));
464 if (is_error)
465 {
466 ui_out_text (uiout, _("decode error ("));
467 ui_out_field_int (uiout, "errcode", errcode);
468 ui_out_text (uiout, _("): "));
469 }
470 ui_out_text (uiout, errstr);
471 ui_out_text (uiout, _("]\n"));
472}
473
afedecd3
MM
474/* Print an unsigned int. */
475
476static void
477ui_out_field_uint (struct ui_out *uiout, const char *fld, unsigned int val)
478{
479 ui_out_field_fmt (uiout, fld, "%u", val);
480}
481
482/* Disassemble a section of the recorded instruction trace. */
483
484static void
23a7fe75 485btrace_insn_history (struct ui_out *uiout,
31fd9caa 486 const struct btrace_thread_info *btinfo,
23a7fe75
MM
487 const struct btrace_insn_iterator *begin,
488 const struct btrace_insn_iterator *end, int flags)
afedecd3
MM
489{
490 struct gdbarch *gdbarch;
23a7fe75 491 struct btrace_insn_iterator it;
afedecd3 492
23a7fe75
MM
493 DEBUG ("itrace (0x%x): [%u; %u)", flags, btrace_insn_number (begin),
494 btrace_insn_number (end));
afedecd3
MM
495
496 gdbarch = target_gdbarch ();
497
23a7fe75 498 for (it = *begin; btrace_insn_cmp (&it, end) != 0; btrace_insn_next (&it, 1))
afedecd3 499 {
23a7fe75
MM
500 const struct btrace_insn *insn;
501
502 insn = btrace_insn_get (&it);
503
31fd9caa
MM
504 /* A NULL instruction indicates a gap in the trace. */
505 if (insn == NULL)
506 {
507 const struct btrace_config *conf;
508
509 conf = btrace_conf (btinfo);
afedecd3 510
31fd9caa
MM
511 /* We have trace so we must have a configuration. */
512 gdb_assert (conf != NULL);
513
514 btrace_ui_out_decode_error (uiout, it.function->errcode,
515 conf->format);
516 }
517 else
518 {
519 /* Print the instruction index. */
520 ui_out_field_uint (uiout, "index", btrace_insn_number (&it));
521 ui_out_text (uiout, "\t");
522
523 /* Disassembly with '/m' flag may not produce the expected result.
524 See PR gdb/11833. */
525 gdb_disassembly (gdbarch, uiout, NULL, flags, 1, insn->pc,
526 insn->pc + 1);
527 }
afedecd3
MM
528 }
529}
530
531/* The to_insn_history method of target record-btrace. */
532
533static void
7a6c5609 534record_btrace_insn_history (struct target_ops *self, int size, int flags)
afedecd3
MM
535{
536 struct btrace_thread_info *btinfo;
23a7fe75
MM
537 struct btrace_insn_history *history;
538 struct btrace_insn_iterator begin, end;
afedecd3
MM
539 struct cleanup *uiout_cleanup;
540 struct ui_out *uiout;
23a7fe75 541 unsigned int context, covered;
afedecd3
MM
542
543 uiout = current_uiout;
544 uiout_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout,
545 "insn history");
afedecd3 546 context = abs (size);
afedecd3
MM
547 if (context == 0)
548 error (_("Bad record instruction-history-size."));
549
23a7fe75
MM
550 btinfo = require_btrace ();
551 history = btinfo->insn_history;
552 if (history == NULL)
afedecd3 553 {
07bbe694 554 struct btrace_insn_iterator *replay;
afedecd3 555
23a7fe75 556 DEBUG ("insn-history (0x%x): %d", flags, size);
afedecd3 557
07bbe694
MM
558 /* If we're replaying, we start at the replay position. Otherwise, we
559 start at the tail of the trace. */
560 replay = btinfo->replay;
561 if (replay != NULL)
562 begin = *replay;
563 else
564 btrace_insn_end (&begin, btinfo);
565
566 /* We start from here and expand in the requested direction. Then we
567 expand in the other direction, as well, to fill up any remaining
568 context. */
569 end = begin;
570 if (size < 0)
571 {
572 /* We want the current position covered, as well. */
573 covered = btrace_insn_next (&end, 1);
574 covered += btrace_insn_prev (&begin, context - covered);
575 covered += btrace_insn_next (&end, context - covered);
576 }
577 else
578 {
579 covered = btrace_insn_next (&end, context);
580 covered += btrace_insn_prev (&begin, context - covered);
581 }
afedecd3
MM
582 }
583 else
584 {
23a7fe75
MM
585 begin = history->begin;
586 end = history->end;
afedecd3 587
23a7fe75
MM
588 DEBUG ("insn-history (0x%x): %d, prev: [%u; %u)", flags, size,
589 btrace_insn_number (&begin), btrace_insn_number (&end));
afedecd3 590
23a7fe75
MM
591 if (size < 0)
592 {
593 end = begin;
594 covered = btrace_insn_prev (&begin, context);
595 }
596 else
597 {
598 begin = end;
599 covered = btrace_insn_next (&end, context);
600 }
afedecd3
MM
601 }
602
23a7fe75 603 if (covered > 0)
31fd9caa 604 btrace_insn_history (uiout, btinfo, &begin, &end, flags);
23a7fe75
MM
605 else
606 {
607 if (size < 0)
608 printf_unfiltered (_("At the start of the branch trace record.\n"));
609 else
610 printf_unfiltered (_("At the end of the branch trace record.\n"));
611 }
afedecd3 612
23a7fe75 613 btrace_set_insn_history (btinfo, &begin, &end);
afedecd3
MM
614 do_cleanups (uiout_cleanup);
615}
616
617/* The to_insn_history_range method of target record-btrace. */
618
619static void
4e99c6b7
TT
620record_btrace_insn_history_range (struct target_ops *self,
621 ULONGEST from, ULONGEST to, int flags)
afedecd3
MM
622{
623 struct btrace_thread_info *btinfo;
23a7fe75
MM
624 struct btrace_insn_history *history;
625 struct btrace_insn_iterator begin, end;
afedecd3
MM
626 struct cleanup *uiout_cleanup;
627 struct ui_out *uiout;
23a7fe75
MM
628 unsigned int low, high;
629 int found;
afedecd3
MM
630
631 uiout = current_uiout;
632 uiout_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout,
633 "insn history");
23a7fe75
MM
634 low = from;
635 high = to;
afedecd3 636
23a7fe75 637 DEBUG ("insn-history (0x%x): [%u; %u)", flags, low, high);
afedecd3
MM
638
639 /* Check for wrap-arounds. */
23a7fe75 640 if (low != from || high != to)
afedecd3
MM
641 error (_("Bad range."));
642
0688d04e 643 if (high < low)
afedecd3
MM
644 error (_("Bad range."));
645
23a7fe75 646 btinfo = require_btrace ();
afedecd3 647
23a7fe75
MM
648 found = btrace_find_insn_by_number (&begin, btinfo, low);
649 if (found == 0)
650 error (_("Range out of bounds."));
afedecd3 651
23a7fe75
MM
652 found = btrace_find_insn_by_number (&end, btinfo, high);
653 if (found == 0)
0688d04e
MM
654 {
655 /* Silently truncate the range. */
656 btrace_insn_end (&end, btinfo);
657 }
658 else
659 {
660 /* We want both begin and end to be inclusive. */
661 btrace_insn_next (&end, 1);
662 }
afedecd3 663
31fd9caa 664 btrace_insn_history (uiout, btinfo, &begin, &end, flags);
23a7fe75 665 btrace_set_insn_history (btinfo, &begin, &end);
afedecd3
MM
666
667 do_cleanups (uiout_cleanup);
668}
669
670/* The to_insn_history_from method of target record-btrace. */
671
672static void
9abc3ff3
TT
673record_btrace_insn_history_from (struct target_ops *self,
674 ULONGEST from, int size, int flags)
afedecd3
MM
675{
676 ULONGEST begin, end, context;
677
678 context = abs (size);
0688d04e
MM
679 if (context == 0)
680 error (_("Bad record instruction-history-size."));
afedecd3
MM
681
682 if (size < 0)
683 {
684 end = from;
685
686 if (from < context)
687 begin = 0;
688 else
0688d04e 689 begin = from - context + 1;
afedecd3
MM
690 }
691 else
692 {
693 begin = from;
0688d04e 694 end = from + context - 1;
afedecd3
MM
695
696 /* Check for wrap-around. */
697 if (end < begin)
698 end = ULONGEST_MAX;
699 }
700
4e99c6b7 701 record_btrace_insn_history_range (self, begin, end, flags);
afedecd3
MM
702}
703
704/* Print the instruction number range for a function call history line. */
705
706static void
23a7fe75
MM
707btrace_call_history_insn_range (struct ui_out *uiout,
708 const struct btrace_function *bfun)
afedecd3 709{
7acbe133
MM
710 unsigned int begin, end, size;
711
712 size = VEC_length (btrace_insn_s, bfun->insn);
713 gdb_assert (size > 0);
afedecd3 714
23a7fe75 715 begin = bfun->insn_offset;
7acbe133 716 end = begin + size - 1;
afedecd3 717
23a7fe75 718 ui_out_field_uint (uiout, "insn begin", begin);
8710b709 719 ui_out_text (uiout, ",");
23a7fe75 720 ui_out_field_uint (uiout, "insn end", end);
afedecd3
MM
721}
722
ce0dfbea
MM
723/* Compute the lowest and highest source line for the instructions in BFUN
724 and return them in PBEGIN and PEND.
725 Ignore instructions that can't be mapped to BFUN, e.g. instructions that
726 result from inlining or macro expansion. */
727
728static void
729btrace_compute_src_line_range (const struct btrace_function *bfun,
730 int *pbegin, int *pend)
731{
732 struct btrace_insn *insn;
733 struct symtab *symtab;
734 struct symbol *sym;
735 unsigned int idx;
736 int begin, end;
737
738 begin = INT_MAX;
739 end = INT_MIN;
740
741 sym = bfun->sym;
742 if (sym == NULL)
743 goto out;
744
745 symtab = symbol_symtab (sym);
746
747 for (idx = 0; VEC_iterate (btrace_insn_s, bfun->insn, idx, insn); ++idx)
748 {
749 struct symtab_and_line sal;
750
751 sal = find_pc_line (insn->pc, 0);
752 if (sal.symtab != symtab || sal.line == 0)
753 continue;
754
755 begin = min (begin, sal.line);
756 end = max (end, sal.line);
757 }
758
759 out:
760 *pbegin = begin;
761 *pend = end;
762}
763
afedecd3
MM
764/* Print the source line information for a function call history line. */
765
766static void
23a7fe75
MM
767btrace_call_history_src_line (struct ui_out *uiout,
768 const struct btrace_function *bfun)
afedecd3
MM
769{
770 struct symbol *sym;
23a7fe75 771 int begin, end;
afedecd3
MM
772
773 sym = bfun->sym;
774 if (sym == NULL)
775 return;
776
777 ui_out_field_string (uiout, "file",
08be3fe3 778 symtab_to_filename_for_display (symbol_symtab (sym)));
afedecd3 779
ce0dfbea 780 btrace_compute_src_line_range (bfun, &begin, &end);
23a7fe75 781 if (end < begin)
afedecd3
MM
782 return;
783
784 ui_out_text (uiout, ":");
23a7fe75 785 ui_out_field_int (uiout, "min line", begin);
afedecd3 786
23a7fe75 787 if (end == begin)
afedecd3
MM
788 return;
789
8710b709 790 ui_out_text (uiout, ",");
23a7fe75 791 ui_out_field_int (uiout, "max line", end);
afedecd3
MM
792}
793
0b722aec
MM
794/* Get the name of a branch trace function. */
795
796static const char *
797btrace_get_bfun_name (const struct btrace_function *bfun)
798{
799 struct minimal_symbol *msym;
800 struct symbol *sym;
801
802 if (bfun == NULL)
803 return "??";
804
805 msym = bfun->msym;
806 sym = bfun->sym;
807
808 if (sym != NULL)
809 return SYMBOL_PRINT_NAME (sym);
810 else if (msym != NULL)
efd66ac6 811 return MSYMBOL_PRINT_NAME (msym);
0b722aec
MM
812 else
813 return "??";
814}
815
afedecd3
MM
816/* Disassemble a section of the recorded function trace. */
817
818static void
23a7fe75 819btrace_call_history (struct ui_out *uiout,
8710b709 820 const struct btrace_thread_info *btinfo,
23a7fe75
MM
821 const struct btrace_call_iterator *begin,
822 const struct btrace_call_iterator *end,
afedecd3
MM
823 enum record_print_flag flags)
824{
23a7fe75 825 struct btrace_call_iterator it;
afedecd3 826
23a7fe75
MM
827 DEBUG ("ftrace (0x%x): [%u; %u)", flags, btrace_call_number (begin),
828 btrace_call_number (end));
afedecd3 829
23a7fe75 830 for (it = *begin; btrace_call_cmp (&it, end) < 0; btrace_call_next (&it, 1))
afedecd3 831 {
23a7fe75
MM
832 const struct btrace_function *bfun;
833 struct minimal_symbol *msym;
834 struct symbol *sym;
835
836 bfun = btrace_call_get (&it);
23a7fe75 837 sym = bfun->sym;
0b722aec 838 msym = bfun->msym;
23a7fe75 839
afedecd3 840 /* Print the function index. */
23a7fe75 841 ui_out_field_uint (uiout, "index", bfun->number);
afedecd3
MM
842 ui_out_text (uiout, "\t");
843
31fd9caa
MM
844 /* Indicate gaps in the trace. */
845 if (bfun->errcode != 0)
846 {
847 const struct btrace_config *conf;
848
849 conf = btrace_conf (btinfo);
850
851 /* We have trace so we must have a configuration. */
852 gdb_assert (conf != NULL);
853
854 btrace_ui_out_decode_error (uiout, bfun->errcode, conf->format);
855
856 continue;
857 }
858
8710b709
MM
859 if ((flags & RECORD_PRINT_INDENT_CALLS) != 0)
860 {
861 int level = bfun->level + btinfo->level, i;
862
863 for (i = 0; i < level; ++i)
864 ui_out_text (uiout, " ");
865 }
866
867 if (sym != NULL)
868 ui_out_field_string (uiout, "function", SYMBOL_PRINT_NAME (sym));
869 else if (msym != NULL)
efd66ac6 870 ui_out_field_string (uiout, "function", MSYMBOL_PRINT_NAME (msym));
8710b709
MM
871 else if (!ui_out_is_mi_like_p (uiout))
872 ui_out_field_string (uiout, "function", "??");
873
1e038f67 874 if ((flags & RECORD_PRINT_INSN_RANGE) != 0)
afedecd3 875 {
8710b709 876 ui_out_text (uiout, _("\tinst "));
23a7fe75 877 btrace_call_history_insn_range (uiout, bfun);
afedecd3
MM
878 }
879
1e038f67 880 if ((flags & RECORD_PRINT_SRC_LINE) != 0)
afedecd3 881 {
8710b709 882 ui_out_text (uiout, _("\tat "));
23a7fe75 883 btrace_call_history_src_line (uiout, bfun);
afedecd3
MM
884 }
885
afedecd3
MM
886 ui_out_text (uiout, "\n");
887 }
888}
889
890/* The to_call_history method of target record-btrace. */
891
892static void
5df2fcba 893record_btrace_call_history (struct target_ops *self, int size, int flags)
afedecd3
MM
894{
895 struct btrace_thread_info *btinfo;
23a7fe75
MM
896 struct btrace_call_history *history;
897 struct btrace_call_iterator begin, end;
afedecd3
MM
898 struct cleanup *uiout_cleanup;
899 struct ui_out *uiout;
23a7fe75 900 unsigned int context, covered;
afedecd3
MM
901
902 uiout = current_uiout;
903 uiout_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout,
904 "insn history");
afedecd3 905 context = abs (size);
afedecd3
MM
906 if (context == 0)
907 error (_("Bad record function-call-history-size."));
908
23a7fe75
MM
909 btinfo = require_btrace ();
910 history = btinfo->call_history;
911 if (history == NULL)
afedecd3 912 {
07bbe694 913 struct btrace_insn_iterator *replay;
afedecd3 914
23a7fe75 915 DEBUG ("call-history (0x%x): %d", flags, size);
afedecd3 916
07bbe694
MM
917 /* If we're replaying, we start at the replay position. Otherwise, we
918 start at the tail of the trace. */
919 replay = btinfo->replay;
920 if (replay != NULL)
921 {
922 begin.function = replay->function;
923 begin.btinfo = btinfo;
924 }
925 else
926 btrace_call_end (&begin, btinfo);
927
928 /* We start from here and expand in the requested direction. Then we
929 expand in the other direction, as well, to fill up any remaining
930 context. */
931 end = begin;
932 if (size < 0)
933 {
934 /* We want the current position covered, as well. */
935 covered = btrace_call_next (&end, 1);
936 covered += btrace_call_prev (&begin, context - covered);
937 covered += btrace_call_next (&end, context - covered);
938 }
939 else
940 {
941 covered = btrace_call_next (&end, context);
942 covered += btrace_call_prev (&begin, context- covered);
943 }
afedecd3
MM
944 }
945 else
946 {
23a7fe75
MM
947 begin = history->begin;
948 end = history->end;
afedecd3 949
23a7fe75
MM
950 DEBUG ("call-history (0x%x): %d, prev: [%u; %u)", flags, size,
951 btrace_call_number (&begin), btrace_call_number (&end));
afedecd3 952
23a7fe75
MM
953 if (size < 0)
954 {
955 end = begin;
956 covered = btrace_call_prev (&begin, context);
957 }
958 else
959 {
960 begin = end;
961 covered = btrace_call_next (&end, context);
962 }
afedecd3
MM
963 }
964
23a7fe75 965 if (covered > 0)
8710b709 966 btrace_call_history (uiout, btinfo, &begin, &end, flags);
23a7fe75
MM
967 else
968 {
969 if (size < 0)
970 printf_unfiltered (_("At the start of the branch trace record.\n"));
971 else
972 printf_unfiltered (_("At the end of the branch trace record.\n"));
973 }
afedecd3 974
23a7fe75 975 btrace_set_call_history (btinfo, &begin, &end);
afedecd3
MM
976 do_cleanups (uiout_cleanup);
977}
978
979/* The to_call_history_range method of target record-btrace. */
980
981static void
f0d960ea
TT
982record_btrace_call_history_range (struct target_ops *self,
983 ULONGEST from, ULONGEST to, int flags)
afedecd3
MM
984{
985 struct btrace_thread_info *btinfo;
23a7fe75
MM
986 struct btrace_call_history *history;
987 struct btrace_call_iterator begin, end;
afedecd3
MM
988 struct cleanup *uiout_cleanup;
989 struct ui_out *uiout;
23a7fe75
MM
990 unsigned int low, high;
991 int found;
afedecd3
MM
992
993 uiout = current_uiout;
994 uiout_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout,
995 "func history");
23a7fe75
MM
996 low = from;
997 high = to;
afedecd3 998
23a7fe75 999 DEBUG ("call-history (0x%x): [%u; %u)", flags, low, high);
afedecd3
MM
1000
1001 /* Check for wrap-arounds. */
23a7fe75 1002 if (low != from || high != to)
afedecd3
MM
1003 error (_("Bad range."));
1004
0688d04e 1005 if (high < low)
afedecd3
MM
1006 error (_("Bad range."));
1007
23a7fe75 1008 btinfo = require_btrace ();
afedecd3 1009
23a7fe75
MM
1010 found = btrace_find_call_by_number (&begin, btinfo, low);
1011 if (found == 0)
1012 error (_("Range out of bounds."));
afedecd3 1013
23a7fe75
MM
1014 found = btrace_find_call_by_number (&end, btinfo, high);
1015 if (found == 0)
0688d04e
MM
1016 {
1017 /* Silently truncate the range. */
1018 btrace_call_end (&end, btinfo);
1019 }
1020 else
1021 {
1022 /* We want both begin and end to be inclusive. */
1023 btrace_call_next (&end, 1);
1024 }
afedecd3 1025
8710b709 1026 btrace_call_history (uiout, btinfo, &begin, &end, flags);
23a7fe75 1027 btrace_set_call_history (btinfo, &begin, &end);
afedecd3
MM
1028
1029 do_cleanups (uiout_cleanup);
1030}
1031
1032/* The to_call_history_from method of target record-btrace. */
1033
1034static void
ec0aea04
TT
1035record_btrace_call_history_from (struct target_ops *self,
1036 ULONGEST from, int size, int flags)
afedecd3
MM
1037{
1038 ULONGEST begin, end, context;
1039
1040 context = abs (size);
0688d04e
MM
1041 if (context == 0)
1042 error (_("Bad record function-call-history-size."));
afedecd3
MM
1043
1044 if (size < 0)
1045 {
1046 end = from;
1047
1048 if (from < context)
1049 begin = 0;
1050 else
0688d04e 1051 begin = from - context + 1;
afedecd3
MM
1052 }
1053 else
1054 {
1055 begin = from;
0688d04e 1056 end = from + context - 1;
afedecd3
MM
1057
1058 /* Check for wrap-around. */
1059 if (end < begin)
1060 end = ULONGEST_MAX;
1061 }
1062
f0d960ea 1063 record_btrace_call_history_range (self, begin, end, flags);
afedecd3
MM
1064}
1065
07bbe694
MM
1066/* The to_record_is_replaying method of target record-btrace. */
1067
1068static int
1c63c994 1069record_btrace_is_replaying (struct target_ops *self)
07bbe694
MM
1070{
1071 struct thread_info *tp;
1072
034f788c 1073 ALL_NON_EXITED_THREADS (tp)
07bbe694
MM
1074 if (btrace_is_replaying (tp))
1075 return 1;
1076
1077 return 0;
1078}
1079
633785ff
MM
1080/* The to_xfer_partial method of target record-btrace. */
1081
9b409511 1082static enum target_xfer_status
633785ff
MM
1083record_btrace_xfer_partial (struct target_ops *ops, enum target_object object,
1084 const char *annex, gdb_byte *readbuf,
1085 const gdb_byte *writebuf, ULONGEST offset,
9b409511 1086 ULONGEST len, ULONGEST *xfered_len)
633785ff
MM
1087{
1088 struct target_ops *t;
1089
1090 /* Filter out requests that don't make sense during replay. */
67b5c0c1 1091 if (replay_memory_access == replay_memory_access_read_only
aef92902 1092 && !record_btrace_generating_corefile
67b5c0c1 1093 && record_btrace_is_replaying (ops))
633785ff
MM
1094 {
1095 switch (object)
1096 {
1097 case TARGET_OBJECT_MEMORY:
1098 {
1099 struct target_section *section;
1100
1101 /* We do not allow writing memory in general. */
1102 if (writebuf != NULL)
9b409511
YQ
1103 {
1104 *xfered_len = len;
bc113b4e 1105 return TARGET_XFER_UNAVAILABLE;
9b409511 1106 }
633785ff
MM
1107
1108 /* We allow reading readonly memory. */
1109 section = target_section_by_addr (ops, offset);
1110 if (section != NULL)
1111 {
1112 /* Check if the section we found is readonly. */
1113 if ((bfd_get_section_flags (section->the_bfd_section->owner,
1114 section->the_bfd_section)
1115 & SEC_READONLY) != 0)
1116 {
1117 /* Truncate the request to fit into this section. */
1118 len = min (len, section->endaddr - offset);
1119 break;
1120 }
1121 }
1122
9b409511 1123 *xfered_len = len;
bc113b4e 1124 return TARGET_XFER_UNAVAILABLE;
633785ff
MM
1125 }
1126 }
1127 }
1128
1129 /* Forward the request. */
e75fdfca
TT
1130 ops = ops->beneath;
1131 return ops->to_xfer_partial (ops, object, annex, readbuf, writebuf,
1132 offset, len, xfered_len);
633785ff
MM
1133}
1134
1135/* The to_insert_breakpoint method of target record-btrace. */
1136
1137static int
1138record_btrace_insert_breakpoint (struct target_ops *ops,
1139 struct gdbarch *gdbarch,
1140 struct bp_target_info *bp_tgt)
1141{
67b5c0c1
MM
1142 const char *old;
1143 int ret;
633785ff
MM
1144
1145 /* Inserting breakpoints requires accessing memory. Allow it for the
1146 duration of this function. */
67b5c0c1
MM
1147 old = replay_memory_access;
1148 replay_memory_access = replay_memory_access_read_write;
633785ff
MM
1149
1150 ret = 0;
492d29ea
PA
1151 TRY
1152 {
1153 ret = ops->beneath->to_insert_breakpoint (ops->beneath, gdbarch, bp_tgt);
1154 }
492d29ea
PA
1155 CATCH (except, RETURN_MASK_ALL)
1156 {
6c63c96a 1157 replay_memory_access = old;
492d29ea
PA
1158 throw_exception (except);
1159 }
1160 END_CATCH
6c63c96a 1161 replay_memory_access = old;
633785ff
MM
1162
1163 return ret;
1164}
1165
1166/* The to_remove_breakpoint method of target record-btrace. */
1167
1168static int
1169record_btrace_remove_breakpoint (struct target_ops *ops,
1170 struct gdbarch *gdbarch,
1171 struct bp_target_info *bp_tgt)
1172{
67b5c0c1
MM
1173 const char *old;
1174 int ret;
633785ff
MM
1175
1176 /* Removing breakpoints requires accessing memory. Allow it for the
1177 duration of this function. */
67b5c0c1
MM
1178 old = replay_memory_access;
1179 replay_memory_access = replay_memory_access_read_write;
633785ff
MM
1180
1181 ret = 0;
492d29ea
PA
1182 TRY
1183 {
1184 ret = ops->beneath->to_remove_breakpoint (ops->beneath, gdbarch, bp_tgt);
1185 }
492d29ea
PA
1186 CATCH (except, RETURN_MASK_ALL)
1187 {
6c63c96a 1188 replay_memory_access = old;
492d29ea
PA
1189 throw_exception (except);
1190 }
1191 END_CATCH
6c63c96a 1192 replay_memory_access = old;
633785ff
MM
1193
1194 return ret;
1195}
1196
1f3ef581
MM
1197/* The to_fetch_registers method of target record-btrace. */
1198
1199static void
1200record_btrace_fetch_registers (struct target_ops *ops,
1201 struct regcache *regcache, int regno)
1202{
1203 struct btrace_insn_iterator *replay;
1204 struct thread_info *tp;
1205
1206 tp = find_thread_ptid (inferior_ptid);
1207 gdb_assert (tp != NULL);
1208
1209 replay = tp->btrace.replay;
aef92902 1210 if (replay != NULL && !record_btrace_generating_corefile)
1f3ef581
MM
1211 {
1212 const struct btrace_insn *insn;
1213 struct gdbarch *gdbarch;
1214 int pcreg;
1215
1216 gdbarch = get_regcache_arch (regcache);
1217 pcreg = gdbarch_pc_regnum (gdbarch);
1218 if (pcreg < 0)
1219 return;
1220
1221 /* We can only provide the PC register. */
1222 if (regno >= 0 && regno != pcreg)
1223 return;
1224
1225 insn = btrace_insn_get (replay);
1226 gdb_assert (insn != NULL);
1227
1228 regcache_raw_supply (regcache, regno, &insn->pc);
1229 }
1230 else
1231 {
e75fdfca 1232 struct target_ops *t = ops->beneath;
1f3ef581 1233
e75fdfca 1234 t->to_fetch_registers (t, regcache, regno);
1f3ef581
MM
1235 }
1236}
1237
1238/* The to_store_registers method of target record-btrace. */
1239
1240static void
1241record_btrace_store_registers (struct target_ops *ops,
1242 struct regcache *regcache, int regno)
1243{
1244 struct target_ops *t;
1245
aef92902 1246 if (!record_btrace_generating_corefile && record_btrace_is_replaying (ops))
1f3ef581
MM
1247 error (_("This record target does not allow writing registers."));
1248
1249 gdb_assert (may_write_registers != 0);
1250
e75fdfca
TT
1251 t = ops->beneath;
1252 t->to_store_registers (t, regcache, regno);
1f3ef581
MM
1253}
1254
1255/* The to_prepare_to_store method of target record-btrace. */
1256
1257static void
1258record_btrace_prepare_to_store (struct target_ops *ops,
1259 struct regcache *regcache)
1260{
1261 struct target_ops *t;
1262
aef92902 1263 if (!record_btrace_generating_corefile && record_btrace_is_replaying (ops))
1f3ef581
MM
1264 return;
1265
e75fdfca
TT
1266 t = ops->beneath;
1267 t->to_prepare_to_store (t, regcache);
1f3ef581
MM
1268}
1269
0b722aec
MM
1270/* The branch trace frame cache. */
1271
1272struct btrace_frame_cache
1273{
1274 /* The thread. */
1275 struct thread_info *tp;
1276
1277 /* The frame info. */
1278 struct frame_info *frame;
1279
1280 /* The branch trace function segment. */
1281 const struct btrace_function *bfun;
1282};
1283
1284/* A struct btrace_frame_cache hash table indexed by NEXT. */
1285
1286static htab_t bfcache;
1287
1288/* hash_f for htab_create_alloc of bfcache. */
1289
1290static hashval_t
1291bfcache_hash (const void *arg)
1292{
1293 const struct btrace_frame_cache *cache = arg;
1294
1295 return htab_hash_pointer (cache->frame);
1296}
1297
1298/* eq_f for htab_create_alloc of bfcache. */
1299
1300static int
1301bfcache_eq (const void *arg1, const void *arg2)
1302{
1303 const struct btrace_frame_cache *cache1 = arg1;
1304 const struct btrace_frame_cache *cache2 = arg2;
1305
1306 return cache1->frame == cache2->frame;
1307}
1308
1309/* Create a new btrace frame cache. */
1310
1311static struct btrace_frame_cache *
1312bfcache_new (struct frame_info *frame)
1313{
1314 struct btrace_frame_cache *cache;
1315 void **slot;
1316
1317 cache = FRAME_OBSTACK_ZALLOC (struct btrace_frame_cache);
1318 cache->frame = frame;
1319
1320 slot = htab_find_slot (bfcache, cache, INSERT);
1321 gdb_assert (*slot == NULL);
1322 *slot = cache;
1323
1324 return cache;
1325}
1326
1327/* Extract the branch trace function from a branch trace frame. */
1328
1329static const struct btrace_function *
1330btrace_get_frame_function (struct frame_info *frame)
1331{
1332 const struct btrace_frame_cache *cache;
1333 const struct btrace_function *bfun;
1334 struct btrace_frame_cache pattern;
1335 void **slot;
1336
1337 pattern.frame = frame;
1338
1339 slot = htab_find_slot (bfcache, &pattern, NO_INSERT);
1340 if (slot == NULL)
1341 return NULL;
1342
1343 cache = *slot;
1344 return cache->bfun;
1345}
1346
cecac1ab
MM
1347/* Implement stop_reason method for record_btrace_frame_unwind. */
1348
1349static enum unwind_stop_reason
1350record_btrace_frame_unwind_stop_reason (struct frame_info *this_frame,
1351 void **this_cache)
1352{
0b722aec
MM
1353 const struct btrace_frame_cache *cache;
1354 const struct btrace_function *bfun;
1355
1356 cache = *this_cache;
1357 bfun = cache->bfun;
1358 gdb_assert (bfun != NULL);
1359
1360 if (bfun->up == NULL)
1361 return UNWIND_UNAVAILABLE;
1362
1363 return UNWIND_NO_REASON;
cecac1ab
MM
1364}
1365
1366/* Implement this_id method for record_btrace_frame_unwind. */
1367
1368static void
1369record_btrace_frame_this_id (struct frame_info *this_frame, void **this_cache,
1370 struct frame_id *this_id)
1371{
0b722aec
MM
1372 const struct btrace_frame_cache *cache;
1373 const struct btrace_function *bfun;
1374 CORE_ADDR code, special;
1375
1376 cache = *this_cache;
1377
1378 bfun = cache->bfun;
1379 gdb_assert (bfun != NULL);
1380
1381 while (bfun->segment.prev != NULL)
1382 bfun = bfun->segment.prev;
1383
1384 code = get_frame_func (this_frame);
1385 special = bfun->number;
1386
1387 *this_id = frame_id_build_unavailable_stack_special (code, special);
1388
1389 DEBUG ("[frame] %s id: (!stack, pc=%s, special=%s)",
1390 btrace_get_bfun_name (cache->bfun),
1391 core_addr_to_string_nz (this_id->code_addr),
1392 core_addr_to_string_nz (this_id->special_addr));
cecac1ab
MM
1393}
1394
1395/* Implement prev_register method for record_btrace_frame_unwind. */
1396
1397static struct value *
1398record_btrace_frame_prev_register (struct frame_info *this_frame,
1399 void **this_cache,
1400 int regnum)
1401{
0b722aec
MM
1402 const struct btrace_frame_cache *cache;
1403 const struct btrace_function *bfun, *caller;
1404 const struct btrace_insn *insn;
1405 struct gdbarch *gdbarch;
1406 CORE_ADDR pc;
1407 int pcreg;
1408
1409 gdbarch = get_frame_arch (this_frame);
1410 pcreg = gdbarch_pc_regnum (gdbarch);
1411 if (pcreg < 0 || regnum != pcreg)
1412 throw_error (NOT_AVAILABLE_ERROR,
1413 _("Registers are not available in btrace record history"));
1414
1415 cache = *this_cache;
1416 bfun = cache->bfun;
1417 gdb_assert (bfun != NULL);
1418
1419 caller = bfun->up;
1420 if (caller == NULL)
1421 throw_error (NOT_AVAILABLE_ERROR,
1422 _("No caller in btrace record history"));
1423
1424 if ((bfun->flags & BFUN_UP_LINKS_TO_RET) != 0)
1425 {
1426 insn = VEC_index (btrace_insn_s, caller->insn, 0);
1427 pc = insn->pc;
1428 }
1429 else
1430 {
1431 insn = VEC_last (btrace_insn_s, caller->insn);
1432 pc = insn->pc;
1433
1434 pc += gdb_insn_length (gdbarch, pc);
1435 }
1436
1437 DEBUG ("[frame] unwound PC in %s on level %d: %s",
1438 btrace_get_bfun_name (bfun), bfun->level,
1439 core_addr_to_string_nz (pc));
1440
1441 return frame_unwind_got_address (this_frame, regnum, pc);
cecac1ab
MM
1442}
1443
1444/* Implement sniffer method for record_btrace_frame_unwind. */
1445
1446static int
1447record_btrace_frame_sniffer (const struct frame_unwind *self,
1448 struct frame_info *this_frame,
1449 void **this_cache)
1450{
0b722aec
MM
1451 const struct btrace_function *bfun;
1452 struct btrace_frame_cache *cache;
cecac1ab 1453 struct thread_info *tp;
0b722aec 1454 struct frame_info *next;
cecac1ab
MM
1455
1456 /* THIS_FRAME does not contain a reference to its thread. */
1457 tp = find_thread_ptid (inferior_ptid);
1458 gdb_assert (tp != NULL);
1459
0b722aec
MM
1460 bfun = NULL;
1461 next = get_next_frame (this_frame);
1462 if (next == NULL)
1463 {
1464 const struct btrace_insn_iterator *replay;
1465
1466 replay = tp->btrace.replay;
1467 if (replay != NULL)
1468 bfun = replay->function;
1469 }
1470 else
1471 {
1472 const struct btrace_function *callee;
1473
1474 callee = btrace_get_frame_function (next);
1475 if (callee != NULL && (callee->flags & BFUN_UP_LINKS_TO_TAILCALL) == 0)
1476 bfun = callee->up;
1477 }
1478
1479 if (bfun == NULL)
1480 return 0;
1481
1482 DEBUG ("[frame] sniffed frame for %s on level %d",
1483 btrace_get_bfun_name (bfun), bfun->level);
1484
1485 /* This is our frame. Initialize the frame cache. */
1486 cache = bfcache_new (this_frame);
1487 cache->tp = tp;
1488 cache->bfun = bfun;
1489
1490 *this_cache = cache;
1491 return 1;
1492}
1493
1494/* Implement sniffer method for record_btrace_tailcall_frame_unwind. */
1495
1496static int
1497record_btrace_tailcall_frame_sniffer (const struct frame_unwind *self,
1498 struct frame_info *this_frame,
1499 void **this_cache)
1500{
1501 const struct btrace_function *bfun, *callee;
1502 struct btrace_frame_cache *cache;
1503 struct frame_info *next;
1504
1505 next = get_next_frame (this_frame);
1506 if (next == NULL)
1507 return 0;
1508
1509 callee = btrace_get_frame_function (next);
1510 if (callee == NULL)
1511 return 0;
1512
1513 if ((callee->flags & BFUN_UP_LINKS_TO_TAILCALL) == 0)
1514 return 0;
1515
1516 bfun = callee->up;
1517 if (bfun == NULL)
1518 return 0;
1519
1520 DEBUG ("[frame] sniffed tailcall frame for %s on level %d",
1521 btrace_get_bfun_name (bfun), bfun->level);
1522
1523 /* This is our frame. Initialize the frame cache. */
1524 cache = bfcache_new (this_frame);
1525 cache->tp = find_thread_ptid (inferior_ptid);
1526 cache->bfun = bfun;
1527
1528 *this_cache = cache;
1529 return 1;
1530}
1531
1532static void
1533record_btrace_frame_dealloc_cache (struct frame_info *self, void *this_cache)
1534{
1535 struct btrace_frame_cache *cache;
1536 void **slot;
1537
1538 cache = this_cache;
1539
1540 slot = htab_find_slot (bfcache, cache, NO_INSERT);
1541 gdb_assert (slot != NULL);
1542
1543 htab_remove_elt (bfcache, cache);
cecac1ab
MM
1544}
1545
1546/* btrace recording does not store previous memory content, neither the stack
1547 frames content. Any unwinding would return errorneous results as the stack
1548 contents no longer matches the changed PC value restored from history.
1549 Therefore this unwinder reports any possibly unwound registers as
1550 <unavailable>. */
1551
0b722aec 1552const struct frame_unwind record_btrace_frame_unwind =
cecac1ab
MM
1553{
1554 NORMAL_FRAME,
1555 record_btrace_frame_unwind_stop_reason,
1556 record_btrace_frame_this_id,
1557 record_btrace_frame_prev_register,
1558 NULL,
0b722aec
MM
1559 record_btrace_frame_sniffer,
1560 record_btrace_frame_dealloc_cache
1561};
1562
1563const struct frame_unwind record_btrace_tailcall_frame_unwind =
1564{
1565 TAILCALL_FRAME,
1566 record_btrace_frame_unwind_stop_reason,
1567 record_btrace_frame_this_id,
1568 record_btrace_frame_prev_register,
1569 NULL,
1570 record_btrace_tailcall_frame_sniffer,
1571 record_btrace_frame_dealloc_cache
cecac1ab 1572};
b2f4cfde 1573
ac01945b
TT
1574/* Implement the to_get_unwinder method. */
1575
1576static const struct frame_unwind *
1577record_btrace_to_get_unwinder (struct target_ops *self)
1578{
1579 return &record_btrace_frame_unwind;
1580}
1581
1582/* Implement the to_get_tailcall_unwinder method. */
1583
1584static const struct frame_unwind *
1585record_btrace_to_get_tailcall_unwinder (struct target_ops *self)
1586{
1587 return &record_btrace_tailcall_frame_unwind;
1588}
1589
52834460
MM
1590/* Indicate that TP should be resumed according to FLAG. */
1591
1592static void
1593record_btrace_resume_thread (struct thread_info *tp,
1594 enum btrace_thread_flag flag)
1595{
1596 struct btrace_thread_info *btinfo;
1597
1598 DEBUG ("resuming %d (%s): %u", tp->num, target_pid_to_str (tp->ptid), flag);
1599
1600 btinfo = &tp->btrace;
1601
1602 if ((btinfo->flags & BTHR_MOVE) != 0)
1603 error (_("Thread already moving."));
1604
1605 /* Fetch the latest branch trace. */
1606 btrace_fetch (tp);
1607
1608 btinfo->flags |= flag;
1609}
1610
1611/* Find the thread to resume given a PTID. */
1612
1613static struct thread_info *
1614record_btrace_find_resume_thread (ptid_t ptid)
1615{
1616 struct thread_info *tp;
1617
1618 /* When asked to resume everything, we pick the current thread. */
1619 if (ptid_equal (minus_one_ptid, ptid) || ptid_is_pid (ptid))
1620 ptid = inferior_ptid;
1621
1622 return find_thread_ptid (ptid);
1623}
1624
1625/* Start replaying a thread. */
1626
1627static struct btrace_insn_iterator *
1628record_btrace_start_replaying (struct thread_info *tp)
1629{
52834460
MM
1630 struct btrace_insn_iterator *replay;
1631 struct btrace_thread_info *btinfo;
1632 int executing;
1633
1634 btinfo = &tp->btrace;
1635 replay = NULL;
1636
1637 /* We can't start replaying without trace. */
1638 if (btinfo->begin == NULL)
1639 return NULL;
1640
1641 /* Clear the executing flag to allow changes to the current frame.
1642 We are not actually running, yet. We just started a reverse execution
1643 command or a record goto command.
1644 For the latter, EXECUTING is false and this has no effect.
1645 For the former, EXECUTING is true and we're in to_wait, about to
1646 move the thread. Since we need to recompute the stack, we temporarily
1647 set EXECUTING to flase. */
1648 executing = is_executing (tp->ptid);
1649 set_executing (tp->ptid, 0);
1650
1651 /* GDB stores the current frame_id when stepping in order to detects steps
1652 into subroutines.
1653 Since frames are computed differently when we're replaying, we need to
1654 recompute those stored frames and fix them up so we can still detect
1655 subroutines after we started replaying. */
492d29ea 1656 TRY
52834460
MM
1657 {
1658 struct frame_info *frame;
1659 struct frame_id frame_id;
1660 int upd_step_frame_id, upd_step_stack_frame_id;
1661
1662 /* The current frame without replaying - computed via normal unwind. */
1663 frame = get_current_frame ();
1664 frame_id = get_frame_id (frame);
1665
1666 /* Check if we need to update any stepping-related frame id's. */
1667 upd_step_frame_id = frame_id_eq (frame_id,
1668 tp->control.step_frame_id);
1669 upd_step_stack_frame_id = frame_id_eq (frame_id,
1670 tp->control.step_stack_frame_id);
1671
1672 /* We start replaying at the end of the branch trace. This corresponds
1673 to the current instruction. */
1674 replay = xmalloc (sizeof (*replay));
1675 btrace_insn_end (replay, btinfo);
1676
31fd9caa
MM
1677 /* Skip gaps at the end of the trace. */
1678 while (btrace_insn_get (replay) == NULL)
1679 {
1680 unsigned int steps;
1681
1682 steps = btrace_insn_prev (replay, 1);
1683 if (steps == 0)
1684 error (_("No trace."));
1685 }
1686
52834460
MM
1687 /* We're not replaying, yet. */
1688 gdb_assert (btinfo->replay == NULL);
1689 btinfo->replay = replay;
1690
1691 /* Make sure we're not using any stale registers. */
1692 registers_changed_ptid (tp->ptid);
1693
1694 /* The current frame with replaying - computed via btrace unwind. */
1695 frame = get_current_frame ();
1696 frame_id = get_frame_id (frame);
1697
1698 /* Replace stepping related frames where necessary. */
1699 if (upd_step_frame_id)
1700 tp->control.step_frame_id = frame_id;
1701 if (upd_step_stack_frame_id)
1702 tp->control.step_stack_frame_id = frame_id;
1703 }
492d29ea 1704 CATCH (except, RETURN_MASK_ALL)
52834460 1705 {
6c63c96a
PA
1706 /* Restore the previous execution state. */
1707 set_executing (tp->ptid, executing);
1708
52834460
MM
1709 xfree (btinfo->replay);
1710 btinfo->replay = NULL;
1711
1712 registers_changed_ptid (tp->ptid);
1713
1714 throw_exception (except);
1715 }
492d29ea 1716 END_CATCH
52834460 1717
6c63c96a
PA
1718 /* Restore the previous execution state. */
1719 set_executing (tp->ptid, executing);
1720
52834460
MM
1721 return replay;
1722}
1723
1724/* Stop replaying a thread. */
1725
1726static void
1727record_btrace_stop_replaying (struct thread_info *tp)
1728{
1729 struct btrace_thread_info *btinfo;
1730
1731 btinfo = &tp->btrace;
1732
1733 xfree (btinfo->replay);
1734 btinfo->replay = NULL;
1735
1736 /* Make sure we're not leaving any stale registers. */
1737 registers_changed_ptid (tp->ptid);
1738}
1739
b2f4cfde
MM
1740/* The to_resume method of target record-btrace. */
1741
1742static void
1743record_btrace_resume (struct target_ops *ops, ptid_t ptid, int step,
1744 enum gdb_signal signal)
1745{
52834460
MM
1746 struct thread_info *tp, *other;
1747 enum btrace_thread_flag flag;
1748
1749 DEBUG ("resume %s: %s", target_pid_to_str (ptid), step ? "step" : "cont");
1750
70ad5bff
MM
1751 /* Store the execution direction of the last resume. */
1752 record_btrace_resume_exec_dir = execution_direction;
1753
52834460
MM
1754 tp = record_btrace_find_resume_thread (ptid);
1755 if (tp == NULL)
1756 error (_("Cannot find thread to resume."));
1757
1758 /* Stop replaying other threads if the thread to resume is not replaying. */
1759 if (!btrace_is_replaying (tp) && execution_direction != EXEC_REVERSE)
034f788c 1760 ALL_NON_EXITED_THREADS (other)
52834460
MM
1761 record_btrace_stop_replaying (other);
1762
b2f4cfde 1763 /* As long as we're not replaying, just forward the request. */
1c63c994 1764 if (!record_btrace_is_replaying (ops) && execution_direction != EXEC_REVERSE)
b2f4cfde 1765 {
e75fdfca
TT
1766 ops = ops->beneath;
1767 return ops->to_resume (ops, ptid, step, signal);
b2f4cfde
MM
1768 }
1769
52834460
MM
1770 /* Compute the btrace thread flag for the requested move. */
1771 if (step == 0)
1772 flag = execution_direction == EXEC_REVERSE ? BTHR_RCONT : BTHR_CONT;
1773 else
1774 flag = execution_direction == EXEC_REVERSE ? BTHR_RSTEP : BTHR_STEP;
1775
1776 /* At the moment, we only move a single thread. We could also move
1777 all threads in parallel by single-stepping each resumed thread
1778 until the first runs into an event.
1779 When we do that, we would want to continue all other threads.
1780 For now, just resume one thread to not confuse to_wait. */
1781 record_btrace_resume_thread (tp, flag);
1782
1783 /* We just indicate the resume intent here. The actual stepping happens in
1784 record_btrace_wait below. */
70ad5bff
MM
1785
1786 /* Async support. */
1787 if (target_can_async_p ())
1788 {
6a3753b3 1789 target_async (1);
70ad5bff
MM
1790 mark_async_event_handler (record_btrace_async_inferior_event_handler);
1791 }
52834460
MM
1792}
1793
1794/* Find a thread to move. */
1795
1796static struct thread_info *
1797record_btrace_find_thread_to_move (ptid_t ptid)
1798{
1799 struct thread_info *tp;
1800
1801 /* First check the parameter thread. */
1802 tp = find_thread_ptid (ptid);
1803 if (tp != NULL && (tp->btrace.flags & BTHR_MOVE) != 0)
1804 return tp;
1805
1806 /* Otherwise, find one other thread that has been resumed. */
034f788c 1807 ALL_NON_EXITED_THREADS (tp)
52834460
MM
1808 if ((tp->btrace.flags & BTHR_MOVE) != 0)
1809 return tp;
1810
1811 return NULL;
1812}
1813
1814/* Return a target_waitstatus indicating that we ran out of history. */
1815
1816static struct target_waitstatus
1817btrace_step_no_history (void)
1818{
1819 struct target_waitstatus status;
1820
1821 status.kind = TARGET_WAITKIND_NO_HISTORY;
1822
1823 return status;
1824}
1825
1826/* Return a target_waitstatus indicating that a step finished. */
1827
1828static struct target_waitstatus
1829btrace_step_stopped (void)
1830{
1831 struct target_waitstatus status;
1832
1833 status.kind = TARGET_WAITKIND_STOPPED;
1834 status.value.sig = GDB_SIGNAL_TRAP;
1835
1836 return status;
1837}
1838
1839/* Clear the record histories. */
1840
1841static void
1842record_btrace_clear_histories (struct btrace_thread_info *btinfo)
1843{
1844 xfree (btinfo->insn_history);
1845 xfree (btinfo->call_history);
1846
1847 btinfo->insn_history = NULL;
1848 btinfo->call_history = NULL;
1849}
1850
1851/* Step a single thread. */
1852
1853static struct target_waitstatus
1854record_btrace_step_thread (struct thread_info *tp)
1855{
1856 struct btrace_insn_iterator *replay, end;
1857 struct btrace_thread_info *btinfo;
1858 struct address_space *aspace;
1859 struct inferior *inf;
1860 enum btrace_thread_flag flags;
1861 unsigned int steps;
1862
e59fa00f
MM
1863 /* We can't step without an execution history. */
1864 if (btrace_is_empty (tp))
1865 return btrace_step_no_history ();
1866
52834460
MM
1867 btinfo = &tp->btrace;
1868 replay = btinfo->replay;
1869
1870 flags = btinfo->flags & BTHR_MOVE;
1871 btinfo->flags &= ~BTHR_MOVE;
1872
1873 DEBUG ("stepping %d (%s): %u", tp->num, target_pid_to_str (tp->ptid), flags);
1874
1875 switch (flags)
1876 {
1877 default:
1878 internal_error (__FILE__, __LINE__, _("invalid stepping type."));
1879
1880 case BTHR_STEP:
1881 /* We're done if we're not replaying. */
1882 if (replay == NULL)
1883 return btrace_step_no_history ();
1884
31fd9caa
MM
1885 /* Skip gaps during replay. */
1886 do
1887 {
1888 steps = btrace_insn_next (replay, 1);
1889 if (steps == 0)
1890 {
1891 record_btrace_stop_replaying (tp);
1892 return btrace_step_no_history ();
1893 }
1894 }
1895 while (btrace_insn_get (replay) == NULL);
52834460
MM
1896
1897 /* Determine the end of the instruction trace. */
1898 btrace_insn_end (&end, btinfo);
1899
1900 /* We stop replaying if we reached the end of the trace. */
1901 if (btrace_insn_cmp (replay, &end) == 0)
1902 record_btrace_stop_replaying (tp);
1903
1904 return btrace_step_stopped ();
1905
1906 case BTHR_RSTEP:
1907 /* Start replaying if we're not already doing so. */
1908 if (replay == NULL)
1909 replay = record_btrace_start_replaying (tp);
1910
31fd9caa
MM
1911 /* If we can't step any further, we reached the end of the history.
1912 Skip gaps during replay. */
1913 do
1914 {
1915 steps = btrace_insn_prev (replay, 1);
1916 if (steps == 0)
1917 return btrace_step_no_history ();
1918
1919 }
1920 while (btrace_insn_get (replay) == NULL);
52834460
MM
1921
1922 return btrace_step_stopped ();
1923
1924 case BTHR_CONT:
1925 /* We're done if we're not replaying. */
1926 if (replay == NULL)
1927 return btrace_step_no_history ();
1928
c9657e70 1929 inf = find_inferior_ptid (tp->ptid);
52834460
MM
1930 aspace = inf->aspace;
1931
1932 /* Determine the end of the instruction trace. */
1933 btrace_insn_end (&end, btinfo);
1934
1935 for (;;)
1936 {
1937 const struct btrace_insn *insn;
1938
31fd9caa
MM
1939 /* Skip gaps during replay. */
1940 do
1941 {
1942 steps = btrace_insn_next (replay, 1);
1943 if (steps == 0)
1944 {
1945 record_btrace_stop_replaying (tp);
1946 return btrace_step_no_history ();
1947 }
1948
1949 insn = btrace_insn_get (replay);
1950 }
1951 while (insn == NULL);
52834460
MM
1952
1953 /* We stop replaying if we reached the end of the trace. */
1954 if (btrace_insn_cmp (replay, &end) == 0)
1955 {
1956 record_btrace_stop_replaying (tp);
1957 return btrace_step_no_history ();
1958 }
1959
52834460
MM
1960 DEBUG ("stepping %d (%s) ... %s", tp->num,
1961 target_pid_to_str (tp->ptid),
1962 core_addr_to_string_nz (insn->pc));
1963
9e8915c6
PA
1964 if (record_check_stopped_by_breakpoint (aspace, insn->pc,
1965 &btinfo->stop_reason))
52834460
MM
1966 return btrace_step_stopped ();
1967 }
1968
1969 case BTHR_RCONT:
1970 /* Start replaying if we're not already doing so. */
1971 if (replay == NULL)
1972 replay = record_btrace_start_replaying (tp);
1973
c9657e70 1974 inf = find_inferior_ptid (tp->ptid);
52834460
MM
1975 aspace = inf->aspace;
1976
1977 for (;;)
1978 {
1979 const struct btrace_insn *insn;
1980
31fd9caa
MM
1981 /* If we can't step any further, we reached the end of the history.
1982 Skip gaps during replay. */
1983 do
1984 {
1985 steps = btrace_insn_prev (replay, 1);
1986 if (steps == 0)
1987 return btrace_step_no_history ();
52834460 1988
31fd9caa
MM
1989 insn = btrace_insn_get (replay);
1990 }
1991 while (insn == NULL);
52834460
MM
1992
1993 DEBUG ("reverse-stepping %d (%s) ... %s", tp->num,
1994 target_pid_to_str (tp->ptid),
1995 core_addr_to_string_nz (insn->pc));
1996
9e8915c6
PA
1997 if (record_check_stopped_by_breakpoint (aspace, insn->pc,
1998 &btinfo->stop_reason))
52834460
MM
1999 return btrace_step_stopped ();
2000 }
2001 }
b2f4cfde
MM
2002}
2003
2004/* The to_wait method of target record-btrace. */
2005
2006static ptid_t
2007record_btrace_wait (struct target_ops *ops, ptid_t ptid,
2008 struct target_waitstatus *status, int options)
2009{
52834460
MM
2010 struct thread_info *tp, *other;
2011
2012 DEBUG ("wait %s (0x%x)", target_pid_to_str (ptid), options);
2013
b2f4cfde 2014 /* As long as we're not replaying, just forward the request. */
1c63c994 2015 if (!record_btrace_is_replaying (ops) && execution_direction != EXEC_REVERSE)
b2f4cfde 2016 {
e75fdfca
TT
2017 ops = ops->beneath;
2018 return ops->to_wait (ops, ptid, status, options);
b2f4cfde
MM
2019 }
2020
52834460
MM
2021 /* Let's find a thread to move. */
2022 tp = record_btrace_find_thread_to_move (ptid);
2023 if (tp == NULL)
2024 {
2025 DEBUG ("wait %s: no thread", target_pid_to_str (ptid));
2026
2027 status->kind = TARGET_WAITKIND_IGNORE;
2028 return minus_one_ptid;
2029 }
2030
2031 /* We only move a single thread. We're not able to correlate threads. */
2032 *status = record_btrace_step_thread (tp);
2033
2034 /* Stop all other threads. */
2035 if (!non_stop)
034f788c 2036 ALL_NON_EXITED_THREADS (other)
52834460
MM
2037 other->btrace.flags &= ~BTHR_MOVE;
2038
2039 /* Start record histories anew from the current position. */
2040 record_btrace_clear_histories (&tp->btrace);
2041
2042 /* We moved the replay position but did not update registers. */
2043 registers_changed_ptid (tp->ptid);
2044
2045 return tp->ptid;
2046}
2047
2048/* The to_can_execute_reverse method of target record-btrace. */
2049
2050static int
19db3e69 2051record_btrace_can_execute_reverse (struct target_ops *self)
52834460
MM
2052{
2053 return 1;
2054}
2055
9e8915c6 2056/* The to_stopped_by_sw_breakpoint method of target record-btrace. */
52834460 2057
9e8915c6
PA
2058static int
2059record_btrace_stopped_by_sw_breakpoint (struct target_ops *ops)
52834460 2060{
1c63c994 2061 if (record_btrace_is_replaying (ops))
9e8915c6
PA
2062 {
2063 struct thread_info *tp = inferior_thread ();
2064
2065 return tp->btrace.stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT;
2066 }
2067
2068 return ops->beneath->to_stopped_by_sw_breakpoint (ops->beneath);
2069}
2070
2071/* The to_supports_stopped_by_sw_breakpoint method of target
2072 record-btrace. */
2073
2074static int
2075record_btrace_supports_stopped_by_sw_breakpoint (struct target_ops *ops)
2076{
2077 if (record_btrace_is_replaying (ops))
2078 return 1;
2079
2080 return ops->beneath->to_supports_stopped_by_sw_breakpoint (ops->beneath);
2081}
2082
2083/* The to_stopped_by_sw_breakpoint method of target record-btrace. */
2084
2085static int
2086record_btrace_stopped_by_hw_breakpoint (struct target_ops *ops)
2087{
2088 if (record_btrace_is_replaying (ops))
2089 {
2090 struct thread_info *tp = inferior_thread ();
2091
2092 return tp->btrace.stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT;
2093 }
2094
2095 return ops->beneath->to_stopped_by_hw_breakpoint (ops->beneath);
2096}
2097
2098/* The to_supports_stopped_by_hw_breakpoint method of target
2099 record-btrace. */
2100
2101static int
2102record_btrace_supports_stopped_by_hw_breakpoint (struct target_ops *ops)
2103{
2104 if (record_btrace_is_replaying (ops))
2105 return 1;
52834460 2106
9e8915c6 2107 return ops->beneath->to_supports_stopped_by_hw_breakpoint (ops->beneath);
b2f4cfde
MM
2108}
2109
e8032dde 2110/* The to_update_thread_list method of target record-btrace. */
e2887aa3
MM
2111
2112static void
e8032dde 2113record_btrace_update_thread_list (struct target_ops *ops)
e2887aa3 2114{
e8032dde 2115 /* We don't add or remove threads during replay. */
1c63c994 2116 if (record_btrace_is_replaying (ops))
e2887aa3
MM
2117 return;
2118
2119 /* Forward the request. */
e75fdfca 2120 ops = ops->beneath;
e8032dde 2121 ops->to_update_thread_list (ops);
e2887aa3
MM
2122}
2123
2124/* The to_thread_alive method of target record-btrace. */
2125
2126static int
2127record_btrace_thread_alive (struct target_ops *ops, ptid_t ptid)
2128{
2129 /* We don't add or remove threads during replay. */
1c63c994 2130 if (record_btrace_is_replaying (ops))
e2887aa3
MM
2131 return find_thread_ptid (ptid) != NULL;
2132
2133 /* Forward the request. */
e75fdfca
TT
2134 ops = ops->beneath;
2135 return ops->to_thread_alive (ops, ptid);
e2887aa3
MM
2136}
2137
066ce621
MM
2138/* Set the replay branch trace instruction iterator. If IT is NULL, replay
2139 is stopped. */
2140
2141static void
2142record_btrace_set_replay (struct thread_info *tp,
2143 const struct btrace_insn_iterator *it)
2144{
2145 struct btrace_thread_info *btinfo;
2146
2147 btinfo = &tp->btrace;
2148
2149 if (it == NULL || it->function == NULL)
52834460 2150 record_btrace_stop_replaying (tp);
066ce621
MM
2151 else
2152 {
2153 if (btinfo->replay == NULL)
52834460 2154 record_btrace_start_replaying (tp);
066ce621
MM
2155 else if (btrace_insn_cmp (btinfo->replay, it) == 0)
2156 return;
2157
2158 *btinfo->replay = *it;
52834460 2159 registers_changed_ptid (tp->ptid);
066ce621
MM
2160 }
2161
52834460
MM
2162 /* Start anew from the new replay position. */
2163 record_btrace_clear_histories (btinfo);
066ce621
MM
2164}
2165
2166/* The to_goto_record_begin method of target record-btrace. */
2167
2168static void
08475817 2169record_btrace_goto_begin (struct target_ops *self)
066ce621
MM
2170{
2171 struct thread_info *tp;
2172 struct btrace_insn_iterator begin;
2173
2174 tp = require_btrace_thread ();
2175
2176 btrace_insn_begin (&begin, &tp->btrace);
2177 record_btrace_set_replay (tp, &begin);
2178
2179 print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
2180}
2181
2182/* The to_goto_record_end method of target record-btrace. */
2183
2184static void
307a1b91 2185record_btrace_goto_end (struct target_ops *ops)
066ce621
MM
2186{
2187 struct thread_info *tp;
2188
2189 tp = require_btrace_thread ();
2190
2191 record_btrace_set_replay (tp, NULL);
2192
2193 print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
2194}
2195
2196/* The to_goto_record method of target record-btrace. */
2197
2198static void
606183ac 2199record_btrace_goto (struct target_ops *self, ULONGEST insn)
066ce621
MM
2200{
2201 struct thread_info *tp;
2202 struct btrace_insn_iterator it;
2203 unsigned int number;
2204 int found;
2205
2206 number = insn;
2207
2208 /* Check for wrap-arounds. */
2209 if (number != insn)
2210 error (_("Instruction number out of range."));
2211
2212 tp = require_btrace_thread ();
2213
2214 found = btrace_find_insn_by_number (&it, &tp->btrace, number);
2215 if (found == 0)
2216 error (_("No such instruction."));
2217
2218 record_btrace_set_replay (tp, &it);
2219
2220 print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
2221}
2222
70ad5bff
MM
2223/* The to_execution_direction target method. */
2224
2225static enum exec_direction_kind
2226record_btrace_execution_direction (struct target_ops *self)
2227{
2228 return record_btrace_resume_exec_dir;
2229}
2230
aef92902
MM
2231/* The to_prepare_to_generate_core target method. */
2232
2233static void
2234record_btrace_prepare_to_generate_core (struct target_ops *self)
2235{
2236 record_btrace_generating_corefile = 1;
2237}
2238
2239/* The to_done_generating_core target method. */
2240
2241static void
2242record_btrace_done_generating_core (struct target_ops *self)
2243{
2244 record_btrace_generating_corefile = 0;
2245}
2246
afedecd3
MM
2247/* Initialize the record-btrace target ops. */
2248
2249static void
2250init_record_btrace_ops (void)
2251{
2252 struct target_ops *ops;
2253
2254 ops = &record_btrace_ops;
2255 ops->to_shortname = "record-btrace";
2256 ops->to_longname = "Branch tracing target";
2257 ops->to_doc = "Collect control-flow trace and provide the execution history.";
2258 ops->to_open = record_btrace_open;
2259 ops->to_close = record_btrace_close;
b7d2e916 2260 ops->to_async = record_btrace_async;
afedecd3
MM
2261 ops->to_detach = record_detach;
2262 ops->to_disconnect = record_disconnect;
2263 ops->to_mourn_inferior = record_mourn_inferior;
2264 ops->to_kill = record_kill;
afedecd3
MM
2265 ops->to_stop_recording = record_btrace_stop_recording;
2266 ops->to_info_record = record_btrace_info;
2267 ops->to_insn_history = record_btrace_insn_history;
2268 ops->to_insn_history_from = record_btrace_insn_history_from;
2269 ops->to_insn_history_range = record_btrace_insn_history_range;
2270 ops->to_call_history = record_btrace_call_history;
2271 ops->to_call_history_from = record_btrace_call_history_from;
2272 ops->to_call_history_range = record_btrace_call_history_range;
07bbe694 2273 ops->to_record_is_replaying = record_btrace_is_replaying;
633785ff
MM
2274 ops->to_xfer_partial = record_btrace_xfer_partial;
2275 ops->to_remove_breakpoint = record_btrace_remove_breakpoint;
2276 ops->to_insert_breakpoint = record_btrace_insert_breakpoint;
1f3ef581
MM
2277 ops->to_fetch_registers = record_btrace_fetch_registers;
2278 ops->to_store_registers = record_btrace_store_registers;
2279 ops->to_prepare_to_store = record_btrace_prepare_to_store;
ac01945b
TT
2280 ops->to_get_unwinder = &record_btrace_to_get_unwinder;
2281 ops->to_get_tailcall_unwinder = &record_btrace_to_get_tailcall_unwinder;
b2f4cfde
MM
2282 ops->to_resume = record_btrace_resume;
2283 ops->to_wait = record_btrace_wait;
e8032dde 2284 ops->to_update_thread_list = record_btrace_update_thread_list;
e2887aa3 2285 ops->to_thread_alive = record_btrace_thread_alive;
066ce621
MM
2286 ops->to_goto_record_begin = record_btrace_goto_begin;
2287 ops->to_goto_record_end = record_btrace_goto_end;
2288 ops->to_goto_record = record_btrace_goto;
52834460 2289 ops->to_can_execute_reverse = record_btrace_can_execute_reverse;
9e8915c6
PA
2290 ops->to_stopped_by_sw_breakpoint = record_btrace_stopped_by_sw_breakpoint;
2291 ops->to_supports_stopped_by_sw_breakpoint
2292 = record_btrace_supports_stopped_by_sw_breakpoint;
2293 ops->to_stopped_by_hw_breakpoint = record_btrace_stopped_by_hw_breakpoint;
2294 ops->to_supports_stopped_by_hw_breakpoint
2295 = record_btrace_supports_stopped_by_hw_breakpoint;
70ad5bff 2296 ops->to_execution_direction = record_btrace_execution_direction;
aef92902
MM
2297 ops->to_prepare_to_generate_core = record_btrace_prepare_to_generate_core;
2298 ops->to_done_generating_core = record_btrace_done_generating_core;
afedecd3
MM
2299 ops->to_stratum = record_stratum;
2300 ops->to_magic = OPS_MAGIC;
2301}
2302
f4abbc16
MM
2303/* Start recording in BTS format. */
2304
2305static void
2306cmd_record_btrace_bts_start (char *args, int from_tty)
2307{
f4abbc16
MM
2308
2309 if (args != NULL && *args != 0)
2310 error (_("Invalid argument."));
2311
2312 record_btrace_conf.format = BTRACE_FORMAT_BTS;
2313
492d29ea
PA
2314 TRY
2315 {
2316 execute_command ("target record-btrace", from_tty);
2317 }
2318 CATCH (exception, RETURN_MASK_ALL)
f4abbc16
MM
2319 {
2320 record_btrace_conf.format = BTRACE_FORMAT_NONE;
2321 throw_exception (exception);
2322 }
492d29ea 2323 END_CATCH
f4abbc16
MM
2324}
2325
afedecd3
MM
2326/* Alias for "target record". */
2327
2328static void
2329cmd_record_btrace_start (char *args, int from_tty)
2330{
f4abbc16 2331
afedecd3
MM
2332 if (args != NULL && *args != 0)
2333 error (_("Invalid argument."));
2334
f4abbc16
MM
2335 record_btrace_conf.format = BTRACE_FORMAT_BTS;
2336
492d29ea
PA
2337 TRY
2338 {
2339 execute_command ("target record-btrace", from_tty);
2340 }
2341 CATCH (exception, RETURN_MASK_ALL)
2342 {
2343 record_btrace_conf.format = BTRACE_FORMAT_NONE;
2344 throw_exception (exception);
2345 }
2346 END_CATCH
afedecd3
MM
2347}
2348
67b5c0c1
MM
2349/* The "set record btrace" command. */
2350
2351static void
2352cmd_set_record_btrace (char *args, int from_tty)
2353{
2354 cmd_show_list (set_record_btrace_cmdlist, from_tty, "");
2355}
2356
2357/* The "show record btrace" command. */
2358
2359static void
2360cmd_show_record_btrace (char *args, int from_tty)
2361{
2362 cmd_show_list (show_record_btrace_cmdlist, from_tty, "");
2363}
2364
2365/* The "show record btrace replay-memory-access" command. */
2366
2367static void
2368cmd_show_replay_memory_access (struct ui_file *file, int from_tty,
2369 struct cmd_list_element *c, const char *value)
2370{
2371 fprintf_filtered (gdb_stdout, _("Replay memory access is %s.\n"),
2372 replay_memory_access);
2373}
2374
d33501a5
MM
2375/* The "set record btrace bts" command. */
2376
2377static void
2378cmd_set_record_btrace_bts (char *args, int from_tty)
2379{
2380 printf_unfiltered (_("\"set record btrace bts\" must be followed "
2381 "by an apporpriate subcommand.\n"));
2382 help_list (set_record_btrace_bts_cmdlist, "set record btrace bts ",
2383 all_commands, gdb_stdout);
2384}
2385
2386/* The "show record btrace bts" command. */
2387
2388static void
2389cmd_show_record_btrace_bts (char *args, int from_tty)
2390{
2391 cmd_show_list (show_record_btrace_bts_cmdlist, from_tty, "");
2392}
2393
afedecd3
MM
2394void _initialize_record_btrace (void);
2395
2396/* Initialize btrace commands. */
2397
2398void
2399_initialize_record_btrace (void)
2400{
f4abbc16
MM
2401 add_prefix_cmd ("btrace", class_obscure, cmd_record_btrace_start,
2402 _("Start branch trace recording."), &record_btrace_cmdlist,
2403 "record btrace ", 0, &record_cmdlist);
afedecd3
MM
2404 add_alias_cmd ("b", "btrace", class_obscure, 1, &record_cmdlist);
2405
f4abbc16
MM
2406 add_cmd ("bts", class_obscure, cmd_record_btrace_bts_start,
2407 _("\
2408Start branch trace recording in Branch Trace Store (BTS) format.\n\n\
2409The processor stores a from/to record for each branch into a cyclic buffer.\n\
2410This format may not be available on all processors."),
2411 &record_btrace_cmdlist);
2412 add_alias_cmd ("bts", "btrace bts", class_obscure, 1, &record_cmdlist);
2413
67b5c0c1
MM
2414 add_prefix_cmd ("btrace", class_support, cmd_set_record_btrace,
2415 _("Set record options"), &set_record_btrace_cmdlist,
2416 "set record btrace ", 0, &set_record_cmdlist);
2417
2418 add_prefix_cmd ("btrace", class_support, cmd_show_record_btrace,
2419 _("Show record options"), &show_record_btrace_cmdlist,
2420 "show record btrace ", 0, &show_record_cmdlist);
2421
2422 add_setshow_enum_cmd ("replay-memory-access", no_class,
2423 replay_memory_access_types, &replay_memory_access, _("\
2424Set what memory accesses are allowed during replay."), _("\
2425Show what memory accesses are allowed during replay."),
2426 _("Default is READ-ONLY.\n\n\
2427The btrace record target does not trace data.\n\
2428The memory therefore corresponds to the live target and not \
2429to the current replay position.\n\n\
2430When READ-ONLY, allow accesses to read-only memory during replay.\n\
2431When READ-WRITE, allow accesses to read-only and read-write memory during \
2432replay."),
2433 NULL, cmd_show_replay_memory_access,
2434 &set_record_btrace_cmdlist,
2435 &show_record_btrace_cmdlist);
2436
d33501a5
MM
2437 add_prefix_cmd ("bts", class_support, cmd_set_record_btrace_bts,
2438 _("Set record btrace bts options"),
2439 &set_record_btrace_bts_cmdlist,
2440 "set record btrace bts ", 0, &set_record_btrace_cmdlist);
2441
2442 add_prefix_cmd ("bts", class_support, cmd_show_record_btrace_bts,
2443 _("Show record btrace bts options"),
2444 &show_record_btrace_bts_cmdlist,
2445 "show record btrace bts ", 0, &show_record_btrace_cmdlist);
2446
2447 add_setshow_uinteger_cmd ("buffer-size", no_class,
2448 &record_btrace_conf.bts.size,
2449 _("Set the record/replay bts buffer size."),
2450 _("Show the record/replay bts buffer size."), _("\
2451When starting recording request a trace buffer of this size. \
2452The actual buffer size may differ from the requested size. \
2453Use \"info record\" to see the actual buffer size.\n\n\
2454Bigger buffers allow longer recording but also take more time to process \
2455the recorded execution trace.\n\n\
2456The trace buffer size may not be changed while recording."), NULL, NULL,
2457 &set_record_btrace_bts_cmdlist,
2458 &show_record_btrace_bts_cmdlist);
2459
afedecd3
MM
2460 init_record_btrace_ops ();
2461 add_target (&record_btrace_ops);
0b722aec
MM
2462
2463 bfcache = htab_create_alloc (50, bfcache_hash, bfcache_eq, NULL,
2464 xcalloc, xfree);
d33501a5
MM
2465
2466 record_btrace_conf.bts.size = 64 * 1024;
afedecd3 2467}
This page took 0.386585 seconds and 4 git commands to generate.