1 /* Branch trace support for GDB, the GNU debugger.
3 Copyright (C) 2013-2014 Free Software Foundation, Inc.
5 Contributed by Intel Corp. <markus.t.metzger@intel.com>
7 This file is part of GDB.
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.
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.
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/>. */
24 #include "gdbthread.h"
29 #include "exceptions.h"
30 #include "cli/cli-utils.h"
34 #include "filenames.h"
36 #include "frame-unwind.h"
39 /* The target_ops of record-btrace. */
40 static struct target_ops record_btrace_ops;
42 /* A new thread observer enabling branch tracing for the new thread. */
43 static struct observer *record_btrace_thread_observer;
45 /* Temporarily allow memory accesses. */
46 static int record_btrace_allow_memory_access;
48 /* Print a record-btrace debug message. Use do ... while (0) to avoid
49 ambiguities when used in if statements. */
51 #define DEBUG(msg, args...) \
54 if (record_debug != 0) \
55 fprintf_unfiltered (gdb_stdlog, \
56 "[record-btrace] " msg "\n", ##args); \
61 /* Update the branch trace for the current thread and return a pointer to its
64 Throws an error if there is no thread or no trace. This function never
67 static struct thread_info *
68 require_btrace_thread (void)
70 struct thread_info *tp;
74 tp = find_thread_ptid (inferior_ptid);
76 error (_("No thread."));
80 if (btrace_is_empty (tp))
81 error (_("No trace."));
86 /* Update the branch trace for the current thread and return a pointer to its
87 branch trace information struct.
89 Throws an error if there is no thread or no trace. This function never
92 static struct btrace_thread_info *
95 struct thread_info *tp;
97 tp = require_btrace_thread ();
102 /* Enable branch tracing for one thread. Warn on errors. */
105 record_btrace_enable_warn (struct thread_info *tp)
107 volatile struct gdb_exception error;
109 TRY_CATCH (error, RETURN_MASK_ERROR)
112 if (error.message != NULL)
113 warning ("%s", error.message);
116 /* Callback function to disable branch tracing for one thread. */
119 record_btrace_disable_callback (void *arg)
121 struct thread_info *tp;
128 /* Enable automatic tracing of new threads. */
131 record_btrace_auto_enable (void)
133 DEBUG ("attach thread observer");
135 record_btrace_thread_observer
136 = observer_attach_new_thread (record_btrace_enable_warn);
139 /* Disable automatic tracing of new threads. */
142 record_btrace_auto_disable (void)
144 /* The observer may have been detached, already. */
145 if (record_btrace_thread_observer == NULL)
148 DEBUG ("detach thread observer");
150 observer_detach_new_thread (record_btrace_thread_observer);
151 record_btrace_thread_observer = NULL;
154 /* The to_open method of target record-btrace. */
157 record_btrace_open (char *args, int from_tty)
159 struct cleanup *disable_chain;
160 struct thread_info *tp;
166 if (!target_has_execution)
167 error (_("The program is not being run."));
169 if (!target_supports_btrace ())
170 error (_("Target does not support branch tracing."));
172 gdb_assert (record_btrace_thread_observer == NULL);
174 disable_chain = make_cleanup (null_cleanup, NULL);
176 if (args == NULL || *args == 0 || number_is_in_list (args, tp->num))
180 make_cleanup (record_btrace_disable_callback, tp);
183 record_btrace_auto_enable ();
185 push_target (&record_btrace_ops);
187 observer_notify_record_changed (current_inferior (), 1);
189 discard_cleanups (disable_chain);
192 /* The to_stop_recording method of target record-btrace. */
195 record_btrace_stop_recording (void)
197 struct thread_info *tp;
199 DEBUG ("stop recording");
201 record_btrace_auto_disable ();
204 if (tp->btrace.target != NULL)
208 /* The to_close method of target record-btrace. */
211 record_btrace_close (void)
213 /* Make sure automatic recording gets disabled even if we did not stop
214 recording before closing the record-btrace target. */
215 record_btrace_auto_disable ();
217 /* We already stopped recording. */
220 /* The to_info_record method of target record-btrace. */
223 record_btrace_info (void)
225 struct btrace_thread_info *btinfo;
226 struct thread_info *tp;
227 unsigned int insns, calls;
231 tp = find_thread_ptid (inferior_ptid);
233 error (_("No thread."));
240 btinfo = &tp->btrace;
242 if (!btrace_is_empty (tp))
244 struct btrace_call_iterator call;
245 struct btrace_insn_iterator insn;
247 btrace_call_end (&call, btinfo);
248 btrace_call_prev (&call, 1);
249 calls = btrace_call_number (&call);
251 btrace_insn_end (&insn, btinfo);
252 btrace_insn_prev (&insn, 1);
253 insns = btrace_insn_number (&insn);
256 printf_unfiltered (_("Recorded %u instructions in %u functions for thread "
257 "%d (%s).\n"), insns, calls, tp->num,
258 target_pid_to_str (tp->ptid));
260 if (btrace_is_replaying (tp))
261 printf_unfiltered (_("Replay in progress. At instruction %u.\n"),
262 btrace_insn_number (btinfo->replay));
265 /* Print an unsigned int. */
268 ui_out_field_uint (struct ui_out *uiout, const char *fld, unsigned int val)
270 ui_out_field_fmt (uiout, fld, "%u", val);
273 /* Disassemble a section of the recorded instruction trace. */
276 btrace_insn_history (struct ui_out *uiout,
277 const struct btrace_insn_iterator *begin,
278 const struct btrace_insn_iterator *end, int flags)
280 struct gdbarch *gdbarch;
281 struct btrace_insn_iterator it;
283 DEBUG ("itrace (0x%x): [%u; %u)", flags, btrace_insn_number (begin),
284 btrace_insn_number (end));
286 gdbarch = target_gdbarch ();
288 for (it = *begin; btrace_insn_cmp (&it, end) != 0; btrace_insn_next (&it, 1))
290 const struct btrace_insn *insn;
292 insn = btrace_insn_get (&it);
294 /* Print the instruction index. */
295 ui_out_field_uint (uiout, "index", btrace_insn_number (&it));
296 ui_out_text (uiout, "\t");
298 /* Disassembly with '/m' flag may not produce the expected result.
300 gdb_disassembly (gdbarch, uiout, NULL, flags, 1, insn->pc, insn->pc + 1);
304 /* The to_insn_history method of target record-btrace. */
307 record_btrace_insn_history (int size, int flags)
309 struct btrace_thread_info *btinfo;
310 struct btrace_insn_history *history;
311 struct btrace_insn_iterator begin, end;
312 struct cleanup *uiout_cleanup;
313 struct ui_out *uiout;
314 unsigned int context, covered;
316 uiout = current_uiout;
317 uiout_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout,
319 context = abs (size);
321 error (_("Bad record instruction-history-size."));
323 btinfo = require_btrace ();
324 history = btinfo->insn_history;
327 struct btrace_insn_iterator *replay;
329 DEBUG ("insn-history (0x%x): %d", flags, size);
331 /* If we're replaying, we start at the replay position. Otherwise, we
332 start at the tail of the trace. */
333 replay = btinfo->replay;
337 btrace_insn_end (&begin, btinfo);
339 /* We start from here and expand in the requested direction. Then we
340 expand in the other direction, as well, to fill up any remaining
345 /* We want the current position covered, as well. */
346 covered = btrace_insn_next (&end, 1);
347 covered += btrace_insn_prev (&begin, context - covered);
348 covered += btrace_insn_next (&end, context - covered);
352 covered = btrace_insn_next (&end, context);
353 covered += btrace_insn_prev (&begin, context - covered);
358 begin = history->begin;
361 DEBUG ("insn-history (0x%x): %d, prev: [%u; %u)", flags, size,
362 btrace_insn_number (&begin), btrace_insn_number (&end));
367 covered = btrace_insn_prev (&begin, context);
372 covered = btrace_insn_next (&end, context);
377 btrace_insn_history (uiout, &begin, &end, flags);
381 printf_unfiltered (_("At the start of the branch trace record.\n"));
383 printf_unfiltered (_("At the end of the branch trace record.\n"));
386 btrace_set_insn_history (btinfo, &begin, &end);
387 do_cleanups (uiout_cleanup);
390 /* The to_insn_history_range method of target record-btrace. */
393 record_btrace_insn_history_range (ULONGEST from, ULONGEST to, int flags)
395 struct btrace_thread_info *btinfo;
396 struct btrace_insn_history *history;
397 struct btrace_insn_iterator begin, end;
398 struct cleanup *uiout_cleanup;
399 struct ui_out *uiout;
400 unsigned int low, high;
403 uiout = current_uiout;
404 uiout_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout,
409 DEBUG ("insn-history (0x%x): [%u; %u)", flags, low, high);
411 /* Check for wrap-arounds. */
412 if (low != from || high != to)
413 error (_("Bad range."));
416 error (_("Bad range."));
418 btinfo = require_btrace ();
420 found = btrace_find_insn_by_number (&begin, btinfo, low);
422 error (_("Range out of bounds."));
424 found = btrace_find_insn_by_number (&end, btinfo, high);
427 /* Silently truncate the range. */
428 btrace_insn_end (&end, btinfo);
432 /* We want both begin and end to be inclusive. */
433 btrace_insn_next (&end, 1);
436 btrace_insn_history (uiout, &begin, &end, flags);
437 btrace_set_insn_history (btinfo, &begin, &end);
439 do_cleanups (uiout_cleanup);
442 /* The to_insn_history_from method of target record-btrace. */
445 record_btrace_insn_history_from (ULONGEST from, int size, int flags)
447 ULONGEST begin, end, context;
449 context = abs (size);
451 error (_("Bad record instruction-history-size."));
460 begin = from - context + 1;
465 end = from + context - 1;
467 /* Check for wrap-around. */
472 record_btrace_insn_history_range (begin, end, flags);
475 /* Print the instruction number range for a function call history line. */
478 btrace_call_history_insn_range (struct ui_out *uiout,
479 const struct btrace_function *bfun)
481 unsigned int begin, end, size;
483 size = VEC_length (btrace_insn_s, bfun->insn);
484 gdb_assert (size > 0);
486 begin = bfun->insn_offset;
487 end = begin + size - 1;
489 ui_out_field_uint (uiout, "insn begin", begin);
490 ui_out_text (uiout, ",");
491 ui_out_field_uint (uiout, "insn end", end);
494 /* Print the source line information for a function call history line. */
497 btrace_call_history_src_line (struct ui_out *uiout,
498 const struct btrace_function *bfun)
507 ui_out_field_string (uiout, "file",
508 symtab_to_filename_for_display (sym->symtab));
510 begin = bfun->lbegin;
516 ui_out_text (uiout, ":");
517 ui_out_field_int (uiout, "min line", begin);
522 ui_out_text (uiout, ",");
523 ui_out_field_int (uiout, "max line", end);
526 /* Get the name of a branch trace function. */
529 btrace_get_bfun_name (const struct btrace_function *bfun)
531 struct minimal_symbol *msym;
541 return SYMBOL_PRINT_NAME (sym);
542 else if (msym != NULL)
543 return SYMBOL_PRINT_NAME (msym);
548 /* Disassemble a section of the recorded function trace. */
551 btrace_call_history (struct ui_out *uiout,
552 const struct btrace_thread_info *btinfo,
553 const struct btrace_call_iterator *begin,
554 const struct btrace_call_iterator *end,
555 enum record_print_flag flags)
557 struct btrace_call_iterator it;
559 DEBUG ("ftrace (0x%x): [%u; %u)", flags, btrace_call_number (begin),
560 btrace_call_number (end));
562 for (it = *begin; btrace_call_cmp (&it, end) < 0; btrace_call_next (&it, 1))
564 const struct btrace_function *bfun;
565 struct minimal_symbol *msym;
568 bfun = btrace_call_get (&it);
572 /* Print the function index. */
573 ui_out_field_uint (uiout, "index", bfun->number);
574 ui_out_text (uiout, "\t");
576 if ((flags & RECORD_PRINT_INDENT_CALLS) != 0)
578 int level = bfun->level + btinfo->level, i;
580 for (i = 0; i < level; ++i)
581 ui_out_text (uiout, " ");
585 ui_out_field_string (uiout, "function", SYMBOL_PRINT_NAME (sym));
586 else if (msym != NULL)
587 ui_out_field_string (uiout, "function", SYMBOL_PRINT_NAME (msym));
588 else if (!ui_out_is_mi_like_p (uiout))
589 ui_out_field_string (uiout, "function", "??");
591 if ((flags & RECORD_PRINT_INSN_RANGE) != 0)
593 ui_out_text (uiout, _("\tinst "));
594 btrace_call_history_insn_range (uiout, bfun);
597 if ((flags & RECORD_PRINT_SRC_LINE) != 0)
599 ui_out_text (uiout, _("\tat "));
600 btrace_call_history_src_line (uiout, bfun);
603 ui_out_text (uiout, "\n");
607 /* The to_call_history method of target record-btrace. */
610 record_btrace_call_history (int size, int flags)
612 struct btrace_thread_info *btinfo;
613 struct btrace_call_history *history;
614 struct btrace_call_iterator begin, end;
615 struct cleanup *uiout_cleanup;
616 struct ui_out *uiout;
617 unsigned int context, covered;
619 uiout = current_uiout;
620 uiout_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout,
622 context = abs (size);
624 error (_("Bad record function-call-history-size."));
626 btinfo = require_btrace ();
627 history = btinfo->call_history;
630 struct btrace_insn_iterator *replay;
632 DEBUG ("call-history (0x%x): %d", flags, size);
634 /* If we're replaying, we start at the replay position. Otherwise, we
635 start at the tail of the trace. */
636 replay = btinfo->replay;
639 begin.function = replay->function;
640 begin.btinfo = btinfo;
643 btrace_call_end (&begin, btinfo);
645 /* We start from here and expand in the requested direction. Then we
646 expand in the other direction, as well, to fill up any remaining
651 /* We want the current position covered, as well. */
652 covered = btrace_call_next (&end, 1);
653 covered += btrace_call_prev (&begin, context - covered);
654 covered += btrace_call_next (&end, context - covered);
658 covered = btrace_call_next (&end, context);
659 covered += btrace_call_prev (&begin, context- covered);
664 begin = history->begin;
667 DEBUG ("call-history (0x%x): %d, prev: [%u; %u)", flags, size,
668 btrace_call_number (&begin), btrace_call_number (&end));
673 covered = btrace_call_prev (&begin, context);
678 covered = btrace_call_next (&end, context);
683 btrace_call_history (uiout, btinfo, &begin, &end, flags);
687 printf_unfiltered (_("At the start of the branch trace record.\n"));
689 printf_unfiltered (_("At the end of the branch trace record.\n"));
692 btrace_set_call_history (btinfo, &begin, &end);
693 do_cleanups (uiout_cleanup);
696 /* The to_call_history_range method of target record-btrace. */
699 record_btrace_call_history_range (ULONGEST from, ULONGEST to, int flags)
701 struct btrace_thread_info *btinfo;
702 struct btrace_call_history *history;
703 struct btrace_call_iterator begin, end;
704 struct cleanup *uiout_cleanup;
705 struct ui_out *uiout;
706 unsigned int low, high;
709 uiout = current_uiout;
710 uiout_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout,
715 DEBUG ("call-history (0x%x): [%u; %u)", flags, low, high);
717 /* Check for wrap-arounds. */
718 if (low != from || high != to)
719 error (_("Bad range."));
722 error (_("Bad range."));
724 btinfo = require_btrace ();
726 found = btrace_find_call_by_number (&begin, btinfo, low);
728 error (_("Range out of bounds."));
730 found = btrace_find_call_by_number (&end, btinfo, high);
733 /* Silently truncate the range. */
734 btrace_call_end (&end, btinfo);
738 /* We want both begin and end to be inclusive. */
739 btrace_call_next (&end, 1);
742 btrace_call_history (uiout, btinfo, &begin, &end, flags);
743 btrace_set_call_history (btinfo, &begin, &end);
745 do_cleanups (uiout_cleanup);
748 /* The to_call_history_from method of target record-btrace. */
751 record_btrace_call_history_from (ULONGEST from, int size, int flags)
753 ULONGEST begin, end, context;
755 context = abs (size);
757 error (_("Bad record function-call-history-size."));
766 begin = from - context + 1;
771 end = from + context - 1;
773 /* Check for wrap-around. */
778 record_btrace_call_history_range (begin, end, flags);
781 /* The to_record_is_replaying method of target record-btrace. */
784 record_btrace_is_replaying (void)
786 struct thread_info *tp;
789 if (btrace_is_replaying (tp))
795 /* The to_xfer_partial method of target record-btrace. */
798 record_btrace_xfer_partial (struct target_ops *ops, enum target_object object,
799 const char *annex, gdb_byte *readbuf,
800 const gdb_byte *writebuf, ULONGEST offset,
803 struct target_ops *t;
805 /* Filter out requests that don't make sense during replay. */
806 if (!record_btrace_allow_memory_access && record_btrace_is_replaying ())
810 case TARGET_OBJECT_MEMORY:
812 struct target_section *section;
814 /* We do not allow writing memory in general. */
815 if (writebuf != NULL)
816 return TARGET_XFER_E_UNAVAILABLE;
818 /* We allow reading readonly memory. */
819 section = target_section_by_addr (ops, offset);
822 /* Check if the section we found is readonly. */
823 if ((bfd_get_section_flags (section->the_bfd_section->owner,
824 section->the_bfd_section)
825 & SEC_READONLY) != 0)
827 /* Truncate the request to fit into this section. */
828 len = min (len, section->endaddr - offset);
833 return TARGET_XFER_E_UNAVAILABLE;
838 /* Forward the request. */
839 for (ops = ops->beneath; ops != NULL; ops = ops->beneath)
840 if (ops->to_xfer_partial != NULL)
841 return ops->to_xfer_partial (ops, object, annex, readbuf, writebuf,
844 return TARGET_XFER_E_UNAVAILABLE;
847 /* The to_insert_breakpoint method of target record-btrace. */
850 record_btrace_insert_breakpoint (struct target_ops *ops,
851 struct gdbarch *gdbarch,
852 struct bp_target_info *bp_tgt)
854 volatile struct gdb_exception except;
857 /* Inserting breakpoints requires accessing memory. Allow it for the
858 duration of this function. */
859 old = record_btrace_allow_memory_access;
860 record_btrace_allow_memory_access = 1;
863 TRY_CATCH (except, RETURN_MASK_ALL)
864 ret = forward_target_insert_breakpoint (ops->beneath, gdbarch, bp_tgt);
866 record_btrace_allow_memory_access = old;
868 if (except.reason < 0)
869 throw_exception (except);
874 /* The to_remove_breakpoint method of target record-btrace. */
877 record_btrace_remove_breakpoint (struct target_ops *ops,
878 struct gdbarch *gdbarch,
879 struct bp_target_info *bp_tgt)
881 volatile struct gdb_exception except;
884 /* Removing breakpoints requires accessing memory. Allow it for the
885 duration of this function. */
886 old = record_btrace_allow_memory_access;
887 record_btrace_allow_memory_access = 1;
890 TRY_CATCH (except, RETURN_MASK_ALL)
891 ret = forward_target_remove_breakpoint (ops->beneath, gdbarch, bp_tgt);
893 record_btrace_allow_memory_access = old;
895 if (except.reason < 0)
896 throw_exception (except);
901 /* The to_fetch_registers method of target record-btrace. */
904 record_btrace_fetch_registers (struct target_ops *ops,
905 struct regcache *regcache, int regno)
907 struct btrace_insn_iterator *replay;
908 struct thread_info *tp;
910 tp = find_thread_ptid (inferior_ptid);
911 gdb_assert (tp != NULL);
913 replay = tp->btrace.replay;
916 const struct btrace_insn *insn;
917 struct gdbarch *gdbarch;
920 gdbarch = get_regcache_arch (regcache);
921 pcreg = gdbarch_pc_regnum (gdbarch);
925 /* We can only provide the PC register. */
926 if (regno >= 0 && regno != pcreg)
929 insn = btrace_insn_get (replay);
930 gdb_assert (insn != NULL);
932 regcache_raw_supply (regcache, regno, &insn->pc);
936 struct target_ops *t;
938 for (t = ops->beneath; t != NULL; t = t->beneath)
939 if (t->to_fetch_registers != NULL)
941 t->to_fetch_registers (t, regcache, regno);
947 /* The to_store_registers method of target record-btrace. */
950 record_btrace_store_registers (struct target_ops *ops,
951 struct regcache *regcache, int regno)
953 struct target_ops *t;
955 if (record_btrace_is_replaying ())
956 error (_("This record target does not allow writing registers."));
958 gdb_assert (may_write_registers != 0);
960 for (t = ops->beneath; t != NULL; t = t->beneath)
961 if (t->to_store_registers != NULL)
963 t->to_store_registers (t, regcache, regno);
970 /* The to_prepare_to_store method of target record-btrace. */
973 record_btrace_prepare_to_store (struct target_ops *ops,
974 struct regcache *regcache)
976 struct target_ops *t;
978 if (record_btrace_is_replaying ())
981 for (t = ops->beneath; t != NULL; t = t->beneath)
982 if (t->to_prepare_to_store != NULL)
984 t->to_prepare_to_store (t, regcache);
989 /* The branch trace frame cache. */
991 struct btrace_frame_cache
994 struct thread_info *tp;
996 /* The frame info. */
997 struct frame_info *frame;
999 /* The branch trace function segment. */
1000 const struct btrace_function *bfun;
1003 /* A struct btrace_frame_cache hash table indexed by NEXT. */
1005 static htab_t bfcache;
1007 /* hash_f for htab_create_alloc of bfcache. */
1010 bfcache_hash (const void *arg)
1012 const struct btrace_frame_cache *cache = arg;
1014 return htab_hash_pointer (cache->frame);
1017 /* eq_f for htab_create_alloc of bfcache. */
1020 bfcache_eq (const void *arg1, const void *arg2)
1022 const struct btrace_frame_cache *cache1 = arg1;
1023 const struct btrace_frame_cache *cache2 = arg2;
1025 return cache1->frame == cache2->frame;
1028 /* Create a new btrace frame cache. */
1030 static struct btrace_frame_cache *
1031 bfcache_new (struct frame_info *frame)
1033 struct btrace_frame_cache *cache;
1036 cache = FRAME_OBSTACK_ZALLOC (struct btrace_frame_cache);
1037 cache->frame = frame;
1039 slot = htab_find_slot (bfcache, cache, INSERT);
1040 gdb_assert (*slot == NULL);
1046 /* Extract the branch trace function from a branch trace frame. */
1048 static const struct btrace_function *
1049 btrace_get_frame_function (struct frame_info *frame)
1051 const struct btrace_frame_cache *cache;
1052 const struct btrace_function *bfun;
1053 struct btrace_frame_cache pattern;
1056 pattern.frame = frame;
1058 slot = htab_find_slot (bfcache, &pattern, NO_INSERT);
1066 /* Implement stop_reason method for record_btrace_frame_unwind. */
1068 static enum unwind_stop_reason
1069 record_btrace_frame_unwind_stop_reason (struct frame_info *this_frame,
1072 const struct btrace_frame_cache *cache;
1073 const struct btrace_function *bfun;
1075 cache = *this_cache;
1077 gdb_assert (bfun != NULL);
1079 if (bfun->up == NULL)
1080 return UNWIND_UNAVAILABLE;
1082 return UNWIND_NO_REASON;
1085 /* Implement this_id method for record_btrace_frame_unwind. */
1088 record_btrace_frame_this_id (struct frame_info *this_frame, void **this_cache,
1089 struct frame_id *this_id)
1091 const struct btrace_frame_cache *cache;
1092 const struct btrace_function *bfun;
1093 CORE_ADDR code, special;
1095 cache = *this_cache;
1098 gdb_assert (bfun != NULL);
1100 while (bfun->segment.prev != NULL)
1101 bfun = bfun->segment.prev;
1103 code = get_frame_func (this_frame);
1104 special = bfun->number;
1106 *this_id = frame_id_build_unavailable_stack_special (code, special);
1108 DEBUG ("[frame] %s id: (!stack, pc=%s, special=%s)",
1109 btrace_get_bfun_name (cache->bfun),
1110 core_addr_to_string_nz (this_id->code_addr),
1111 core_addr_to_string_nz (this_id->special_addr));
1114 /* Implement prev_register method for record_btrace_frame_unwind. */
1116 static struct value *
1117 record_btrace_frame_prev_register (struct frame_info *this_frame,
1121 const struct btrace_frame_cache *cache;
1122 const struct btrace_function *bfun, *caller;
1123 const struct btrace_insn *insn;
1124 struct gdbarch *gdbarch;
1128 gdbarch = get_frame_arch (this_frame);
1129 pcreg = gdbarch_pc_regnum (gdbarch);
1130 if (pcreg < 0 || regnum != pcreg)
1131 throw_error (NOT_AVAILABLE_ERROR,
1132 _("Registers are not available in btrace record history"));
1134 cache = *this_cache;
1136 gdb_assert (bfun != NULL);
1140 throw_error (NOT_AVAILABLE_ERROR,
1141 _("No caller in btrace record history"));
1143 if ((bfun->flags & BFUN_UP_LINKS_TO_RET) != 0)
1145 insn = VEC_index (btrace_insn_s, caller->insn, 0);
1150 insn = VEC_last (btrace_insn_s, caller->insn);
1153 pc += gdb_insn_length (gdbarch, pc);
1156 DEBUG ("[frame] unwound PC in %s on level %d: %s",
1157 btrace_get_bfun_name (bfun), bfun->level,
1158 core_addr_to_string_nz (pc));
1160 return frame_unwind_got_address (this_frame, regnum, pc);
1163 /* Implement sniffer method for record_btrace_frame_unwind. */
1166 record_btrace_frame_sniffer (const struct frame_unwind *self,
1167 struct frame_info *this_frame,
1170 const struct btrace_function *bfun;
1171 struct btrace_frame_cache *cache;
1172 struct thread_info *tp;
1173 struct frame_info *next;
1175 /* THIS_FRAME does not contain a reference to its thread. */
1176 tp = find_thread_ptid (inferior_ptid);
1177 gdb_assert (tp != NULL);
1180 next = get_next_frame (this_frame);
1183 const struct btrace_insn_iterator *replay;
1185 replay = tp->btrace.replay;
1187 bfun = replay->function;
1191 const struct btrace_function *callee;
1193 callee = btrace_get_frame_function (next);
1194 if (callee != NULL && (callee->flags & BFUN_UP_LINKS_TO_TAILCALL) == 0)
1201 DEBUG ("[frame] sniffed frame for %s on level %d",
1202 btrace_get_bfun_name (bfun), bfun->level);
1204 /* This is our frame. Initialize the frame cache. */
1205 cache = bfcache_new (this_frame);
1209 *this_cache = cache;
1213 /* Implement sniffer method for record_btrace_tailcall_frame_unwind. */
1216 record_btrace_tailcall_frame_sniffer (const struct frame_unwind *self,
1217 struct frame_info *this_frame,
1220 const struct btrace_function *bfun, *callee;
1221 struct btrace_frame_cache *cache;
1222 struct frame_info *next;
1224 next = get_next_frame (this_frame);
1228 callee = btrace_get_frame_function (next);
1232 if ((callee->flags & BFUN_UP_LINKS_TO_TAILCALL) == 0)
1239 DEBUG ("[frame] sniffed tailcall frame for %s on level %d",
1240 btrace_get_bfun_name (bfun), bfun->level);
1242 /* This is our frame. Initialize the frame cache. */
1243 cache = bfcache_new (this_frame);
1244 cache->tp = find_thread_ptid (inferior_ptid);
1247 *this_cache = cache;
1252 record_btrace_frame_dealloc_cache (struct frame_info *self, void *this_cache)
1254 struct btrace_frame_cache *cache;
1259 slot = htab_find_slot (bfcache, cache, NO_INSERT);
1260 gdb_assert (slot != NULL);
1262 htab_remove_elt (bfcache, cache);
1265 /* btrace recording does not store previous memory content, neither the stack
1266 frames content. Any unwinding would return errorneous results as the stack
1267 contents no longer matches the changed PC value restored from history.
1268 Therefore this unwinder reports any possibly unwound registers as
1271 const struct frame_unwind record_btrace_frame_unwind =
1274 record_btrace_frame_unwind_stop_reason,
1275 record_btrace_frame_this_id,
1276 record_btrace_frame_prev_register,
1278 record_btrace_frame_sniffer,
1279 record_btrace_frame_dealloc_cache
1282 const struct frame_unwind record_btrace_tailcall_frame_unwind =
1285 record_btrace_frame_unwind_stop_reason,
1286 record_btrace_frame_this_id,
1287 record_btrace_frame_prev_register,
1289 record_btrace_tailcall_frame_sniffer,
1290 record_btrace_frame_dealloc_cache
1293 /* The to_resume method of target record-btrace. */
1296 record_btrace_resume (struct target_ops *ops, ptid_t ptid, int step,
1297 enum gdb_signal signal)
1299 /* As long as we're not replaying, just forward the request. */
1300 if (!record_btrace_is_replaying ())
1302 for (ops = ops->beneath; ops != NULL; ops = ops->beneath)
1303 if (ops->to_resume != NULL)
1304 return ops->to_resume (ops, ptid, step, signal);
1306 error (_("Cannot find target for stepping."));
1309 error (_("You can't do this from here. Do 'record goto end', first."));
1312 /* The to_wait method of target record-btrace. */
1315 record_btrace_wait (struct target_ops *ops, ptid_t ptid,
1316 struct target_waitstatus *status, int options)
1318 /* As long as we're not replaying, just forward the request. */
1319 if (!record_btrace_is_replaying ())
1321 for (ops = ops->beneath; ops != NULL; ops = ops->beneath)
1322 if (ops->to_wait != NULL)
1323 return ops->to_wait (ops, ptid, status, options);
1325 error (_("Cannot find target for waiting."));
1328 error (_("You can't do this from here. Do 'record goto end', first."));
1331 /* The to_find_new_threads method of target record-btrace. */
1334 record_btrace_find_new_threads (struct target_ops *ops)
1336 /* Don't expect new threads if we're replaying. */
1337 if (record_btrace_is_replaying ())
1340 /* Forward the request. */
1341 for (ops = ops->beneath; ops != NULL; ops = ops->beneath)
1342 if (ops->to_find_new_threads != NULL)
1344 ops->to_find_new_threads (ops);
1349 /* The to_thread_alive method of target record-btrace. */
1352 record_btrace_thread_alive (struct target_ops *ops, ptid_t ptid)
1354 /* We don't add or remove threads during replay. */
1355 if (record_btrace_is_replaying ())
1356 return find_thread_ptid (ptid) != NULL;
1358 /* Forward the request. */
1359 for (ops = ops->beneath; ops != NULL; ops = ops->beneath)
1360 if (ops->to_thread_alive != NULL)
1361 return ops->to_thread_alive (ops, ptid);
1366 /* Set the replay branch trace instruction iterator. If IT is NULL, replay
1370 record_btrace_set_replay (struct thread_info *tp,
1371 const struct btrace_insn_iterator *it)
1373 struct btrace_thread_info *btinfo;
1375 btinfo = &tp->btrace;
1377 if (it == NULL || it->function == NULL)
1379 if (btinfo->replay == NULL)
1382 xfree (btinfo->replay);
1383 btinfo->replay = NULL;
1387 if (btinfo->replay == NULL)
1388 btinfo->replay = xmalloc (sizeof (*btinfo->replay));
1389 else if (btrace_insn_cmp (btinfo->replay, it) == 0)
1392 *btinfo->replay = *it;
1395 /* Clear the function call and instruction histories so we start anew
1396 from the new replay position. */
1397 xfree (btinfo->insn_history);
1398 xfree (btinfo->call_history);
1400 btinfo->insn_history = NULL;
1401 btinfo->call_history = NULL;
1403 registers_changed_ptid (tp->ptid);
1406 /* The to_goto_record_begin method of target record-btrace. */
1409 record_btrace_goto_begin (void)
1411 struct thread_info *tp;
1412 struct btrace_insn_iterator begin;
1414 tp = require_btrace_thread ();
1416 btrace_insn_begin (&begin, &tp->btrace);
1417 record_btrace_set_replay (tp, &begin);
1419 print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
1422 /* The to_goto_record_end method of target record-btrace. */
1425 record_btrace_goto_end (void)
1427 struct thread_info *tp;
1429 tp = require_btrace_thread ();
1431 record_btrace_set_replay (tp, NULL);
1433 print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
1436 /* The to_goto_record method of target record-btrace. */
1439 record_btrace_goto (ULONGEST insn)
1441 struct thread_info *tp;
1442 struct btrace_insn_iterator it;
1443 unsigned int number;
1448 /* Check for wrap-arounds. */
1450 error (_("Instruction number out of range."));
1452 tp = require_btrace_thread ();
1454 found = btrace_find_insn_by_number (&it, &tp->btrace, number);
1456 error (_("No such instruction."));
1458 record_btrace_set_replay (tp, &it);
1460 print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
1463 /* Initialize the record-btrace target ops. */
1466 init_record_btrace_ops (void)
1468 struct target_ops *ops;
1470 ops = &record_btrace_ops;
1471 ops->to_shortname = "record-btrace";
1472 ops->to_longname = "Branch tracing target";
1473 ops->to_doc = "Collect control-flow trace and provide the execution history.";
1474 ops->to_open = record_btrace_open;
1475 ops->to_close = record_btrace_close;
1476 ops->to_detach = record_detach;
1477 ops->to_disconnect = record_disconnect;
1478 ops->to_mourn_inferior = record_mourn_inferior;
1479 ops->to_kill = record_kill;
1480 ops->to_create_inferior = find_default_create_inferior;
1481 ops->to_stop_recording = record_btrace_stop_recording;
1482 ops->to_info_record = record_btrace_info;
1483 ops->to_insn_history = record_btrace_insn_history;
1484 ops->to_insn_history_from = record_btrace_insn_history_from;
1485 ops->to_insn_history_range = record_btrace_insn_history_range;
1486 ops->to_call_history = record_btrace_call_history;
1487 ops->to_call_history_from = record_btrace_call_history_from;
1488 ops->to_call_history_range = record_btrace_call_history_range;
1489 ops->to_record_is_replaying = record_btrace_is_replaying;
1490 ops->to_xfer_partial = record_btrace_xfer_partial;
1491 ops->to_remove_breakpoint = record_btrace_remove_breakpoint;
1492 ops->to_insert_breakpoint = record_btrace_insert_breakpoint;
1493 ops->to_fetch_registers = record_btrace_fetch_registers;
1494 ops->to_store_registers = record_btrace_store_registers;
1495 ops->to_prepare_to_store = record_btrace_prepare_to_store;
1496 ops->to_get_unwinder = &record_btrace_frame_unwind;
1497 ops->to_get_tailcall_unwinder = &record_btrace_tailcall_frame_unwind;
1498 ops->to_resume = record_btrace_resume;
1499 ops->to_wait = record_btrace_wait;
1500 ops->to_find_new_threads = record_btrace_find_new_threads;
1501 ops->to_thread_alive = record_btrace_thread_alive;
1502 ops->to_goto_record_begin = record_btrace_goto_begin;
1503 ops->to_goto_record_end = record_btrace_goto_end;
1504 ops->to_goto_record = record_btrace_goto;
1505 ops->to_stratum = record_stratum;
1506 ops->to_magic = OPS_MAGIC;
1509 /* Alias for "target record". */
1512 cmd_record_btrace_start (char *args, int from_tty)
1514 if (args != NULL && *args != 0)
1515 error (_("Invalid argument."));
1517 execute_command ("target record-btrace", from_tty);
1520 void _initialize_record_btrace (void);
1522 /* Initialize btrace commands. */
1525 _initialize_record_btrace (void)
1527 add_cmd ("btrace", class_obscure, cmd_record_btrace_start,
1528 _("Start branch trace recording."),
1530 add_alias_cmd ("b", "btrace", class_obscure, 1, &record_cmdlist);
1532 init_record_btrace_ops ();
1533 add_target (&record_btrace_ops);
1535 bfcache = htab_create_alloc (50, bfcache_hash, bfcache_eq, NULL,