record-btrace, frame: supply target-specific unwinder
[external/binutils.git] / gdb / record-btrace.c
1 /* Branch trace support for GDB, the GNU debugger.
2
3    Copyright (C) 2013-2014 Free Software Foundation, Inc.
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"
29 #include "exceptions.h"
30 #include "cli/cli-utils.h"
31 #include "source.h"
32 #include "ui-out.h"
33 #include "symtab.h"
34 #include "filenames.h"
35 #include "regcache.h"
36 #include "frame-unwind.h"
37
38 /* The target_ops of record-btrace.  */
39 static struct target_ops record_btrace_ops;
40
41 /* A new thread observer enabling branch tracing for the new thread.  */
42 static struct observer *record_btrace_thread_observer;
43
44 /* Print a record-btrace debug message.  Use do ... while (0) to avoid
45    ambiguities when used in if statements.  */
46
47 #define DEBUG(msg, args...)                                             \
48   do                                                                    \
49     {                                                                   \
50       if (record_debug != 0)                                            \
51         fprintf_unfiltered (gdb_stdlog,                                 \
52                             "[record-btrace] " msg "\n", ##args);       \
53     }                                                                   \
54   while (0)
55
56
57 /* Update the branch trace for the current thread and return a pointer to its
58    branch trace information struct.
59
60    Throws an error if there is no thread or no trace.  This function never
61    returns NULL.  */
62
63 static struct btrace_thread_info *
64 require_btrace (void)
65 {
66   struct thread_info *tp;
67   struct btrace_thread_info *btinfo;
68
69   DEBUG ("require");
70
71   tp = find_thread_ptid (inferior_ptid);
72   if (tp == NULL)
73     error (_("No thread."));
74
75   btrace_fetch (tp);
76
77   btinfo = &tp->btrace;
78
79   if (btinfo->begin == NULL)
80     error (_("No trace."));
81
82   return btinfo;
83 }
84
85 /* Enable branch tracing for one thread.  Warn on errors.  */
86
87 static void
88 record_btrace_enable_warn (struct thread_info *tp)
89 {
90   volatile struct gdb_exception error;
91
92   TRY_CATCH (error, RETURN_MASK_ERROR)
93     btrace_enable (tp);
94
95   if (error.message != NULL)
96     warning ("%s", error.message);
97 }
98
99 /* Callback function to disable branch tracing for one thread.  */
100
101 static void
102 record_btrace_disable_callback (void *arg)
103 {
104   struct thread_info *tp;
105
106   tp = arg;
107
108   btrace_disable (tp);
109 }
110
111 /* Enable automatic tracing of new threads.  */
112
113 static void
114 record_btrace_auto_enable (void)
115 {
116   DEBUG ("attach thread observer");
117
118   record_btrace_thread_observer
119     = observer_attach_new_thread (record_btrace_enable_warn);
120 }
121
122 /* Disable automatic tracing of new threads.  */
123
124 static void
125 record_btrace_auto_disable (void)
126 {
127   /* The observer may have been detached, already.  */
128   if (record_btrace_thread_observer == NULL)
129     return;
130
131   DEBUG ("detach thread observer");
132
133   observer_detach_new_thread (record_btrace_thread_observer);
134   record_btrace_thread_observer = NULL;
135 }
136
137 /* The to_open method of target record-btrace.  */
138
139 static void
140 record_btrace_open (char *args, int from_tty)
141 {
142   struct cleanup *disable_chain;
143   struct thread_info *tp;
144
145   DEBUG ("open");
146
147   record_preopen ();
148
149   if (!target_has_execution)
150     error (_("The program is not being run."));
151
152   if (!target_supports_btrace ())
153     error (_("Target does not support branch tracing."));
154
155   gdb_assert (record_btrace_thread_observer == NULL);
156
157   disable_chain = make_cleanup (null_cleanup, NULL);
158   ALL_THREADS (tp)
159     if (args == NULL || *args == 0 || number_is_in_list (args, tp->num))
160       {
161         btrace_enable (tp);
162
163         make_cleanup (record_btrace_disable_callback, tp);
164       }
165
166   record_btrace_auto_enable ();
167
168   push_target (&record_btrace_ops);
169
170   observer_notify_record_changed (current_inferior (),  1);
171
172   discard_cleanups (disable_chain);
173 }
174
175 /* The to_stop_recording method of target record-btrace.  */
176
177 static void
178 record_btrace_stop_recording (void)
179 {
180   struct thread_info *tp;
181
182   DEBUG ("stop recording");
183
184   record_btrace_auto_disable ();
185
186   ALL_THREADS (tp)
187     if (tp->btrace.target != NULL)
188       btrace_disable (tp);
189 }
190
191 /* The to_close method of target record-btrace.  */
192
193 static void
194 record_btrace_close (void)
195 {
196   /* Make sure automatic recording gets disabled even if we did not stop
197      recording before closing the record-btrace target.  */
198   record_btrace_auto_disable ();
199
200   /* We already stopped recording.  */
201 }
202
203 /* The to_info_record method of target record-btrace.  */
204
205 static void
206 record_btrace_info (void)
207 {
208   struct btrace_thread_info *btinfo;
209   struct thread_info *tp;
210   unsigned int insns, calls;
211
212   DEBUG ("info");
213
214   tp = find_thread_ptid (inferior_ptid);
215   if (tp == NULL)
216     error (_("No thread."));
217
218   btrace_fetch (tp);
219
220   insns = 0;
221   calls = 0;
222
223   btinfo = &tp->btrace;
224   if (btinfo->begin != NULL)
225     {
226       struct btrace_call_iterator call;
227       struct btrace_insn_iterator insn;
228
229       btrace_call_end (&call, btinfo);
230       btrace_call_prev (&call, 1);
231       calls = btrace_call_number (&call);
232
233       btrace_insn_end (&insn, btinfo);
234       btrace_insn_prev (&insn, 1);
235       insns = btrace_insn_number (&insn);
236     }
237
238   printf_unfiltered (_("Recorded %u instructions in %u functions for thread "
239                        "%d (%s).\n"), insns, calls, tp->num,
240                      target_pid_to_str (tp->ptid));
241
242   if (btrace_is_replaying (tp))
243     printf_unfiltered (_("Replay in progress.  At instruction %u.\n"),
244                        btrace_insn_number (btinfo->replay));
245 }
246
247 /* Print an unsigned int.  */
248
249 static void
250 ui_out_field_uint (struct ui_out *uiout, const char *fld, unsigned int val)
251 {
252   ui_out_field_fmt (uiout, fld, "%u", val);
253 }
254
255 /* Disassemble a section of the recorded instruction trace.  */
256
257 static void
258 btrace_insn_history (struct ui_out *uiout,
259                      const struct btrace_insn_iterator *begin,
260                      const struct btrace_insn_iterator *end, int flags)
261 {
262   struct gdbarch *gdbarch;
263   struct btrace_insn_iterator it;
264
265   DEBUG ("itrace (0x%x): [%u; %u)", flags, btrace_insn_number (begin),
266          btrace_insn_number (end));
267
268   gdbarch = target_gdbarch ();
269
270   for (it = *begin; btrace_insn_cmp (&it, end) != 0; btrace_insn_next (&it, 1))
271     {
272       const struct btrace_insn *insn;
273
274       insn = btrace_insn_get (&it);
275
276       /* Print the instruction index.  */
277       ui_out_field_uint (uiout, "index", btrace_insn_number (&it));
278       ui_out_text (uiout, "\t");
279
280       /* Disassembly with '/m' flag may not produce the expected result.
281          See PR gdb/11833.  */
282       gdb_disassembly (gdbarch, uiout, NULL, flags, 1, insn->pc, insn->pc + 1);
283     }
284 }
285
286 /* The to_insn_history method of target record-btrace.  */
287
288 static void
289 record_btrace_insn_history (int size, int flags)
290 {
291   struct btrace_thread_info *btinfo;
292   struct btrace_insn_history *history;
293   struct btrace_insn_iterator begin, end;
294   struct cleanup *uiout_cleanup;
295   struct ui_out *uiout;
296   unsigned int context, covered;
297
298   uiout = current_uiout;
299   uiout_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout,
300                                                        "insn history");
301   context = abs (size);
302   if (context == 0)
303     error (_("Bad record instruction-history-size."));
304
305   btinfo = require_btrace ();
306   history = btinfo->insn_history;
307   if (history == NULL)
308     {
309       struct btrace_insn_iterator *replay;
310
311       DEBUG ("insn-history (0x%x): %d", flags, size);
312
313       /* If we're replaying, we start at the replay position.  Otherwise, we
314          start at the tail of the trace.  */
315       replay = btinfo->replay;
316       if (replay != NULL)
317         begin = *replay;
318       else
319         btrace_insn_end (&begin, btinfo);
320
321       /* We start from here and expand in the requested direction.  Then we
322          expand in the other direction, as well, to fill up any remaining
323          context.  */
324       end = begin;
325       if (size < 0)
326         {
327           /* We want the current position covered, as well.  */
328           covered = btrace_insn_next (&end, 1);
329           covered += btrace_insn_prev (&begin, context - covered);
330           covered += btrace_insn_next (&end, context - covered);
331         }
332       else
333         {
334           covered = btrace_insn_next (&end, context);
335           covered += btrace_insn_prev (&begin, context - covered);
336         }
337     }
338   else
339     {
340       begin = history->begin;
341       end = history->end;
342
343       DEBUG ("insn-history (0x%x): %d, prev: [%u; %u)", flags, size,
344              btrace_insn_number (&begin), btrace_insn_number (&end));
345
346       if (size < 0)
347         {
348           end = begin;
349           covered = btrace_insn_prev (&begin, context);
350         }
351       else
352         {
353           begin = end;
354           covered = btrace_insn_next (&end, context);
355         }
356     }
357
358   if (covered > 0)
359     btrace_insn_history (uiout, &begin, &end, flags);
360   else
361     {
362       if (size < 0)
363         printf_unfiltered (_("At the start of the branch trace record.\n"));
364       else
365         printf_unfiltered (_("At the end of the branch trace record.\n"));
366     }
367
368   btrace_set_insn_history (btinfo, &begin, &end);
369   do_cleanups (uiout_cleanup);
370 }
371
372 /* The to_insn_history_range method of target record-btrace.  */
373
374 static void
375 record_btrace_insn_history_range (ULONGEST from, ULONGEST to, int flags)
376 {
377   struct btrace_thread_info *btinfo;
378   struct btrace_insn_history *history;
379   struct btrace_insn_iterator begin, end;
380   struct cleanup *uiout_cleanup;
381   struct ui_out *uiout;
382   unsigned int low, high;
383   int found;
384
385   uiout = current_uiout;
386   uiout_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout,
387                                                        "insn history");
388   low = from;
389   high = to;
390
391   DEBUG ("insn-history (0x%x): [%u; %u)", flags, low, high);
392
393   /* Check for wrap-arounds.  */
394   if (low != from || high != to)
395     error (_("Bad range."));
396
397   if (high < low)
398     error (_("Bad range."));
399
400   btinfo = require_btrace ();
401
402   found = btrace_find_insn_by_number (&begin, btinfo, low);
403   if (found == 0)
404     error (_("Range out of bounds."));
405
406   found = btrace_find_insn_by_number (&end, btinfo, high);
407   if (found == 0)
408     {
409       /* Silently truncate the range.  */
410       btrace_insn_end (&end, btinfo);
411     }
412   else
413     {
414       /* We want both begin and end to be inclusive.  */
415       btrace_insn_next (&end, 1);
416     }
417
418   btrace_insn_history (uiout, &begin, &end, flags);
419   btrace_set_insn_history (btinfo, &begin, &end);
420
421   do_cleanups (uiout_cleanup);
422 }
423
424 /* The to_insn_history_from method of target record-btrace.  */
425
426 static void
427 record_btrace_insn_history_from (ULONGEST from, int size, int flags)
428 {
429   ULONGEST begin, end, context;
430
431   context = abs (size);
432   if (context == 0)
433     error (_("Bad record instruction-history-size."));
434
435   if (size < 0)
436     {
437       end = from;
438
439       if (from < context)
440         begin = 0;
441       else
442         begin = from - context + 1;
443     }
444   else
445     {
446       begin = from;
447       end = from + context - 1;
448
449       /* Check for wrap-around.  */
450       if (end < begin)
451         end = ULONGEST_MAX;
452     }
453
454   record_btrace_insn_history_range (begin, end, flags);
455 }
456
457 /* Print the instruction number range for a function call history line.  */
458
459 static void
460 btrace_call_history_insn_range (struct ui_out *uiout,
461                                 const struct btrace_function *bfun)
462 {
463   unsigned int begin, end, size;
464
465   size = VEC_length (btrace_insn_s, bfun->insn);
466   gdb_assert (size > 0);
467
468   begin = bfun->insn_offset;
469   end = begin + size - 1;
470
471   ui_out_field_uint (uiout, "insn begin", begin);
472   ui_out_text (uiout, ",");
473   ui_out_field_uint (uiout, "insn end", end);
474 }
475
476 /* Print the source line information for a function call history line.  */
477
478 static void
479 btrace_call_history_src_line (struct ui_out *uiout,
480                               const struct btrace_function *bfun)
481 {
482   struct symbol *sym;
483   int begin, end;
484
485   sym = bfun->sym;
486   if (sym == NULL)
487     return;
488
489   ui_out_field_string (uiout, "file",
490                        symtab_to_filename_for_display (sym->symtab));
491
492   begin = bfun->lbegin;
493   end = bfun->lend;
494
495   if (end < begin)
496     return;
497
498   ui_out_text (uiout, ":");
499   ui_out_field_int (uiout, "min line", begin);
500
501   if (end == begin)
502     return;
503
504   ui_out_text (uiout, ",");
505   ui_out_field_int (uiout, "max line", end);
506 }
507
508 /* Disassemble a section of the recorded function trace.  */
509
510 static void
511 btrace_call_history (struct ui_out *uiout,
512                      const struct btrace_thread_info *btinfo,
513                      const struct btrace_call_iterator *begin,
514                      const struct btrace_call_iterator *end,
515                      enum record_print_flag flags)
516 {
517   struct btrace_call_iterator it;
518
519   DEBUG ("ftrace (0x%x): [%u; %u)", flags, btrace_call_number (begin),
520          btrace_call_number (end));
521
522   for (it = *begin; btrace_call_cmp (&it, end) < 0; btrace_call_next (&it, 1))
523     {
524       const struct btrace_function *bfun;
525       struct minimal_symbol *msym;
526       struct symbol *sym;
527
528       bfun = btrace_call_get (&it);
529       msym = bfun->msym;
530       sym = bfun->sym;
531
532       /* Print the function index.  */
533       ui_out_field_uint (uiout, "index", bfun->number);
534       ui_out_text (uiout, "\t");
535
536       if ((flags & RECORD_PRINT_INDENT_CALLS) != 0)
537         {
538           int level = bfun->level + btinfo->level, i;
539
540           for (i = 0; i < level; ++i)
541             ui_out_text (uiout, "  ");
542         }
543
544       if (sym != NULL)
545         ui_out_field_string (uiout, "function", SYMBOL_PRINT_NAME (sym));
546       else if (msym != NULL)
547         ui_out_field_string (uiout, "function", SYMBOL_PRINT_NAME (msym));
548       else if (!ui_out_is_mi_like_p (uiout))
549         ui_out_field_string (uiout, "function", "??");
550
551       if ((flags & RECORD_PRINT_INSN_RANGE) != 0)
552         {
553           ui_out_text (uiout, _("\tinst "));
554           btrace_call_history_insn_range (uiout, bfun);
555         }
556
557       if ((flags & RECORD_PRINT_SRC_LINE) != 0)
558         {
559           ui_out_text (uiout, _("\tat "));
560           btrace_call_history_src_line (uiout, bfun);
561         }
562
563       ui_out_text (uiout, "\n");
564     }
565 }
566
567 /* The to_call_history method of target record-btrace.  */
568
569 static void
570 record_btrace_call_history (int size, int flags)
571 {
572   struct btrace_thread_info *btinfo;
573   struct btrace_call_history *history;
574   struct btrace_call_iterator begin, end;
575   struct cleanup *uiout_cleanup;
576   struct ui_out *uiout;
577   unsigned int context, covered;
578
579   uiout = current_uiout;
580   uiout_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout,
581                                                        "insn history");
582   context = abs (size);
583   if (context == 0)
584     error (_("Bad record function-call-history-size."));
585
586   btinfo = require_btrace ();
587   history = btinfo->call_history;
588   if (history == NULL)
589     {
590       struct btrace_insn_iterator *replay;
591
592       DEBUG ("call-history (0x%x): %d", flags, size);
593
594       /* If we're replaying, we start at the replay position.  Otherwise, we
595          start at the tail of the trace.  */
596       replay = btinfo->replay;
597       if (replay != NULL)
598         {
599           begin.function = replay->function;
600           begin.btinfo = btinfo;
601         }
602       else
603         btrace_call_end (&begin, btinfo);
604
605       /* We start from here and expand in the requested direction.  Then we
606          expand in the other direction, as well, to fill up any remaining
607          context.  */
608       end = begin;
609       if (size < 0)
610         {
611           /* We want the current position covered, as well.  */
612           covered = btrace_call_next (&end, 1);
613           covered += btrace_call_prev (&begin, context - covered);
614           covered += btrace_call_next (&end, context - covered);
615         }
616       else
617         {
618           covered = btrace_call_next (&end, context);
619           covered += btrace_call_prev (&begin, context- covered);
620         }
621     }
622   else
623     {
624       begin = history->begin;
625       end = history->end;
626
627       DEBUG ("call-history (0x%x): %d, prev: [%u; %u)", flags, size,
628              btrace_call_number (&begin), btrace_call_number (&end));
629
630       if (size < 0)
631         {
632           end = begin;
633           covered = btrace_call_prev (&begin, context);
634         }
635       else
636         {
637           begin = end;
638           covered = btrace_call_next (&end, context);
639         }
640     }
641
642   if (covered > 0)
643     btrace_call_history (uiout, btinfo, &begin, &end, flags);
644   else
645     {
646       if (size < 0)
647         printf_unfiltered (_("At the start of the branch trace record.\n"));
648       else
649         printf_unfiltered (_("At the end of the branch trace record.\n"));
650     }
651
652   btrace_set_call_history (btinfo, &begin, &end);
653   do_cleanups (uiout_cleanup);
654 }
655
656 /* The to_call_history_range method of target record-btrace.  */
657
658 static void
659 record_btrace_call_history_range (ULONGEST from, ULONGEST to, int flags)
660 {
661   struct btrace_thread_info *btinfo;
662   struct btrace_call_history *history;
663   struct btrace_call_iterator begin, end;
664   struct cleanup *uiout_cleanup;
665   struct ui_out *uiout;
666   unsigned int low, high;
667   int found;
668
669   uiout = current_uiout;
670   uiout_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout,
671                                                        "func history");
672   low = from;
673   high = to;
674
675   DEBUG ("call-history (0x%x): [%u; %u)", flags, low, high);
676
677   /* Check for wrap-arounds.  */
678   if (low != from || high != to)
679     error (_("Bad range."));
680
681   if (high < low)
682     error (_("Bad range."));
683
684   btinfo = require_btrace ();
685
686   found = btrace_find_call_by_number (&begin, btinfo, low);
687   if (found == 0)
688     error (_("Range out of bounds."));
689
690   found = btrace_find_call_by_number (&end, btinfo, high);
691   if (found == 0)
692     {
693       /* Silently truncate the range.  */
694       btrace_call_end (&end, btinfo);
695     }
696   else
697     {
698       /* We want both begin and end to be inclusive.  */
699       btrace_call_next (&end, 1);
700     }
701
702   btrace_call_history (uiout, btinfo, &begin, &end, flags);
703   btrace_set_call_history (btinfo, &begin, &end);
704
705   do_cleanups (uiout_cleanup);
706 }
707
708 /* The to_call_history_from method of target record-btrace.  */
709
710 static void
711 record_btrace_call_history_from (ULONGEST from, int size, int flags)
712 {
713   ULONGEST begin, end, context;
714
715   context = abs (size);
716   if (context == 0)
717     error (_("Bad record function-call-history-size."));
718
719   if (size < 0)
720     {
721       end = from;
722
723       if (from < context)
724         begin = 0;
725       else
726         begin = from - context + 1;
727     }
728   else
729     {
730       begin = from;
731       end = from + context - 1;
732
733       /* Check for wrap-around.  */
734       if (end < begin)
735         end = ULONGEST_MAX;
736     }
737
738   record_btrace_call_history_range (begin, end, flags);
739 }
740
741 /* The to_record_is_replaying method of target record-btrace.  */
742
743 static int
744 record_btrace_is_replaying (void)
745 {
746   struct thread_info *tp;
747
748   ALL_THREADS (tp)
749     if (btrace_is_replaying (tp))
750       return 1;
751
752   return 0;
753 }
754
755 /* The to_fetch_registers method of target record-btrace.  */
756
757 static void
758 record_btrace_fetch_registers (struct target_ops *ops,
759                                struct regcache *regcache, int regno)
760 {
761   struct btrace_insn_iterator *replay;
762   struct thread_info *tp;
763
764   tp = find_thread_ptid (inferior_ptid);
765   gdb_assert (tp != NULL);
766
767   replay = tp->btrace.replay;
768   if (replay != NULL)
769     {
770       const struct btrace_insn *insn;
771       struct gdbarch *gdbarch;
772       int pcreg;
773
774       gdbarch = get_regcache_arch (regcache);
775       pcreg = gdbarch_pc_regnum (gdbarch);
776       if (pcreg < 0)
777         return;
778
779       /* We can only provide the PC register.  */
780       if (regno >= 0 && regno != pcreg)
781         return;
782
783       insn = btrace_insn_get (replay);
784       gdb_assert (insn != NULL);
785
786       regcache_raw_supply (regcache, regno, &insn->pc);
787     }
788   else
789     {
790       struct target_ops *t;
791
792       for (t = ops->beneath; t != NULL; t = t->beneath)
793         if (t->to_fetch_registers != NULL)
794           {
795             t->to_fetch_registers (t, regcache, regno);
796             break;
797           }
798     }
799 }
800
801 /* The to_store_registers method of target record-btrace.  */
802
803 static void
804 record_btrace_store_registers (struct target_ops *ops,
805                                struct regcache *regcache, int regno)
806 {
807   struct target_ops *t;
808
809   if (record_btrace_is_replaying ())
810     error (_("This record target does not allow writing registers."));
811
812   gdb_assert (may_write_registers != 0);
813
814   for (t = ops->beneath; t != NULL; t = t->beneath)
815     if (t->to_store_registers != NULL)
816       {
817         t->to_store_registers (t, regcache, regno);
818         return;
819       }
820
821   noprocess ();
822 }
823
824 /* The to_prepare_to_store method of target record-btrace.  */
825
826 static void
827 record_btrace_prepare_to_store (struct target_ops *ops,
828                                 struct regcache *regcache)
829 {
830   struct target_ops *t;
831
832   if (record_btrace_is_replaying ())
833     return;
834
835   for (t = ops->beneath; t != NULL; t = t->beneath)
836     if (t->to_prepare_to_store != NULL)
837       {
838         t->to_prepare_to_store (t, regcache);
839         return;
840       }
841 }
842
843 /* Implement stop_reason method for record_btrace_frame_unwind.  */
844
845 static enum unwind_stop_reason
846 record_btrace_frame_unwind_stop_reason (struct frame_info *this_frame,
847                                         void **this_cache)
848 {
849   return UNWIND_UNAVAILABLE;
850 }
851
852 /* Implement this_id method for record_btrace_frame_unwind.  */
853
854 static void
855 record_btrace_frame_this_id (struct frame_info *this_frame, void **this_cache,
856                              struct frame_id *this_id)
857 {
858   /* Leave there the outer_frame_id value.  */
859 }
860
861 /* Implement prev_register method for record_btrace_frame_unwind.  */
862
863 static struct value *
864 record_btrace_frame_prev_register (struct frame_info *this_frame,
865                                    void **this_cache,
866                                    int regnum)
867 {
868   throw_error (NOT_AVAILABLE_ERROR,
869               _("Registers are not available in btrace record history"));
870 }
871
872 /* Implement sniffer method for record_btrace_frame_unwind.  */
873
874 static int
875 record_btrace_frame_sniffer (const struct frame_unwind *self,
876                              struct frame_info *this_frame,
877                              void **this_cache)
878 {
879   struct thread_info *tp;
880   struct btrace_thread_info *btinfo;
881   struct btrace_insn_iterator *replay;
882
883   /* THIS_FRAME does not contain a reference to its thread.  */
884   tp = find_thread_ptid (inferior_ptid);
885   gdb_assert (tp != NULL);
886
887   return btrace_is_replaying (tp);
888 }
889
890 /* btrace recording does not store previous memory content, neither the stack
891    frames content.  Any unwinding would return errorneous results as the stack
892    contents no longer matches the changed PC value restored from history.
893    Therefore this unwinder reports any possibly unwound registers as
894    <unavailable>.  */
895
896 static const struct frame_unwind record_btrace_frame_unwind =
897 {
898   NORMAL_FRAME,
899   record_btrace_frame_unwind_stop_reason,
900   record_btrace_frame_this_id,
901   record_btrace_frame_prev_register,
902   NULL,
903   record_btrace_frame_sniffer
904 };
905 /* Initialize the record-btrace target ops.  */
906
907 static void
908 init_record_btrace_ops (void)
909 {
910   struct target_ops *ops;
911
912   ops = &record_btrace_ops;
913   ops->to_shortname = "record-btrace";
914   ops->to_longname = "Branch tracing target";
915   ops->to_doc = "Collect control-flow trace and provide the execution history.";
916   ops->to_open = record_btrace_open;
917   ops->to_close = record_btrace_close;
918   ops->to_detach = record_detach;
919   ops->to_disconnect = record_disconnect;
920   ops->to_mourn_inferior = record_mourn_inferior;
921   ops->to_kill = record_kill;
922   ops->to_create_inferior = find_default_create_inferior;
923   ops->to_stop_recording = record_btrace_stop_recording;
924   ops->to_info_record = record_btrace_info;
925   ops->to_insn_history = record_btrace_insn_history;
926   ops->to_insn_history_from = record_btrace_insn_history_from;
927   ops->to_insn_history_range = record_btrace_insn_history_range;
928   ops->to_call_history = record_btrace_call_history;
929   ops->to_call_history_from = record_btrace_call_history_from;
930   ops->to_call_history_range = record_btrace_call_history_range;
931   ops->to_record_is_replaying = record_btrace_is_replaying;
932   ops->to_fetch_registers = record_btrace_fetch_registers;
933   ops->to_store_registers = record_btrace_store_registers;
934   ops->to_prepare_to_store = record_btrace_prepare_to_store;
935   ops->to_get_unwinder = &record_btrace_frame_unwind;
936   ops->to_stratum = record_stratum;
937   ops->to_magic = OPS_MAGIC;
938 }
939
940 /* Alias for "target record".  */
941
942 static void
943 cmd_record_btrace_start (char *args, int from_tty)
944 {
945   if (args != NULL && *args != 0)
946     error (_("Invalid argument."));
947
948   execute_command ("target record-btrace", from_tty);
949 }
950
951 void _initialize_record_btrace (void);
952
953 /* Initialize btrace commands.  */
954
955 void
956 _initialize_record_btrace (void)
957 {
958   add_cmd ("btrace", class_obscure, cmd_record_btrace_start,
959            _("Start branch trace recording."),
960            &record_cmdlist);
961   add_alias_cmd ("b", "btrace", class_obscure, 1, &record_cmdlist);
962
963   init_record_btrace_ops ();
964   add_target (&record_btrace_ops);
965 }