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;
71 struct btrace_thread_info *btinfo;
75 tp = find_thread_ptid (inferior_ptid);
77 error (_("No thread."));
83 if (btinfo->begin == NULL)
84 error (_("No trace."));
89 /* Update the branch trace for the current thread and return a pointer to its
90 branch trace information struct.
92 Throws an error if there is no thread or no trace. This function never
95 static struct btrace_thread_info *
98 struct thread_info *tp;
100 tp = require_btrace_thread ();
105 /* Enable branch tracing for one thread. Warn on errors. */
108 record_btrace_enable_warn (struct thread_info *tp)
110 volatile struct gdb_exception error;
112 TRY_CATCH (error, RETURN_MASK_ERROR)
115 if (error.message != NULL)
116 warning ("%s", error.message);
119 /* Callback function to disable branch tracing for one thread. */
122 record_btrace_disable_callback (void *arg)
124 struct thread_info *tp;
131 /* Enable automatic tracing of new threads. */
134 record_btrace_auto_enable (void)
136 DEBUG ("attach thread observer");
138 record_btrace_thread_observer
139 = observer_attach_new_thread (record_btrace_enable_warn);
142 /* Disable automatic tracing of new threads. */
145 record_btrace_auto_disable (void)
147 /* The observer may have been detached, already. */
148 if (record_btrace_thread_observer == NULL)
151 DEBUG ("detach thread observer");
153 observer_detach_new_thread (record_btrace_thread_observer);
154 record_btrace_thread_observer = NULL;
157 /* The to_open method of target record-btrace. */
160 record_btrace_open (char *args, int from_tty)
162 struct cleanup *disable_chain;
163 struct thread_info *tp;
169 if (!target_has_execution)
170 error (_("The program is not being run."));
172 if (!target_supports_btrace ())
173 error (_("Target does not support branch tracing."));
175 gdb_assert (record_btrace_thread_observer == NULL);
177 disable_chain = make_cleanup (null_cleanup, NULL);
179 if (args == NULL || *args == 0 || number_is_in_list (args, tp->num))
183 make_cleanup (record_btrace_disable_callback, tp);
186 record_btrace_auto_enable ();
188 push_target (&record_btrace_ops);
190 observer_notify_record_changed (current_inferior (), 1);
192 discard_cleanups (disable_chain);
195 /* The to_stop_recording method of target record-btrace. */
198 record_btrace_stop_recording (void)
200 struct thread_info *tp;
202 DEBUG ("stop recording");
204 record_btrace_auto_disable ();
207 if (tp->btrace.target != NULL)
211 /* The to_close method of target record-btrace. */
214 record_btrace_close (void)
216 /* Make sure automatic recording gets disabled even if we did not stop
217 recording before closing the record-btrace target. */
218 record_btrace_auto_disable ();
220 /* We already stopped recording. */
223 /* The to_info_record method of target record-btrace. */
226 record_btrace_info (void)
228 struct btrace_thread_info *btinfo;
229 struct thread_info *tp;
230 unsigned int insns, calls;
234 tp = find_thread_ptid (inferior_ptid);
236 error (_("No thread."));
243 btinfo = &tp->btrace;
244 if (btinfo->begin != NULL)
246 struct btrace_call_iterator call;
247 struct btrace_insn_iterator insn;
249 btrace_call_end (&call, btinfo);
250 btrace_call_prev (&call, 1);
251 calls = btrace_call_number (&call);
253 btrace_insn_end (&insn, btinfo);
254 btrace_insn_prev (&insn, 1);
255 insns = btrace_insn_number (&insn);
258 printf_unfiltered (_("Recorded %u instructions in %u functions for thread "
259 "%d (%s).\n"), insns, calls, tp->num,
260 target_pid_to_str (tp->ptid));
262 if (btrace_is_replaying (tp))
263 printf_unfiltered (_("Replay in progress. At instruction %u.\n"),
264 btrace_insn_number (btinfo->replay));
267 /* Print an unsigned int. */
270 ui_out_field_uint (struct ui_out *uiout, const char *fld, unsigned int val)
272 ui_out_field_fmt (uiout, fld, "%u", val);
275 /* Disassemble a section of the recorded instruction trace. */
278 btrace_insn_history (struct ui_out *uiout,
279 const struct btrace_insn_iterator *begin,
280 const struct btrace_insn_iterator *end, int flags)
282 struct gdbarch *gdbarch;
283 struct btrace_insn_iterator it;
285 DEBUG ("itrace (0x%x): [%u; %u)", flags, btrace_insn_number (begin),
286 btrace_insn_number (end));
288 gdbarch = target_gdbarch ();
290 for (it = *begin; btrace_insn_cmp (&it, end) != 0; btrace_insn_next (&it, 1))
292 const struct btrace_insn *insn;
294 insn = btrace_insn_get (&it);
296 /* Print the instruction index. */
297 ui_out_field_uint (uiout, "index", btrace_insn_number (&it));
298 ui_out_text (uiout, "\t");
300 /* Disassembly with '/m' flag may not produce the expected result.
302 gdb_disassembly (gdbarch, uiout, NULL, flags, 1, insn->pc, insn->pc + 1);
306 /* The to_insn_history method of target record-btrace. */
309 record_btrace_insn_history (int size, int flags)
311 struct btrace_thread_info *btinfo;
312 struct btrace_insn_history *history;
313 struct btrace_insn_iterator begin, end;
314 struct cleanup *uiout_cleanup;
315 struct ui_out *uiout;
316 unsigned int context, covered;
318 uiout = current_uiout;
319 uiout_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout,
321 context = abs (size);
323 error (_("Bad record instruction-history-size."));
325 btinfo = require_btrace ();
326 history = btinfo->insn_history;
329 struct btrace_insn_iterator *replay;
331 DEBUG ("insn-history (0x%x): %d", flags, size);
333 /* If we're replaying, we start at the replay position. Otherwise, we
334 start at the tail of the trace. */
335 replay = btinfo->replay;
339 btrace_insn_end (&begin, btinfo);
341 /* We start from here and expand in the requested direction. Then we
342 expand in the other direction, as well, to fill up any remaining
347 /* We want the current position covered, as well. */
348 covered = btrace_insn_next (&end, 1);
349 covered += btrace_insn_prev (&begin, context - covered);
350 covered += btrace_insn_next (&end, context - covered);
354 covered = btrace_insn_next (&end, context);
355 covered += btrace_insn_prev (&begin, context - covered);
360 begin = history->begin;
363 DEBUG ("insn-history (0x%x): %d, prev: [%u; %u)", flags, size,
364 btrace_insn_number (&begin), btrace_insn_number (&end));
369 covered = btrace_insn_prev (&begin, context);
374 covered = btrace_insn_next (&end, context);
379 btrace_insn_history (uiout, &begin, &end, flags);
383 printf_unfiltered (_("At the start of the branch trace record.\n"));
385 printf_unfiltered (_("At the end of the branch trace record.\n"));
388 btrace_set_insn_history (btinfo, &begin, &end);
389 do_cleanups (uiout_cleanup);
392 /* The to_insn_history_range method of target record-btrace. */
395 record_btrace_insn_history_range (ULONGEST from, ULONGEST to, int flags)
397 struct btrace_thread_info *btinfo;
398 struct btrace_insn_history *history;
399 struct btrace_insn_iterator begin, end;
400 struct cleanup *uiout_cleanup;
401 struct ui_out *uiout;
402 unsigned int low, high;
405 uiout = current_uiout;
406 uiout_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout,
411 DEBUG ("insn-history (0x%x): [%u; %u)", flags, low, high);
413 /* Check for wrap-arounds. */
414 if (low != from || high != to)
415 error (_("Bad range."));
418 error (_("Bad range."));
420 btinfo = require_btrace ();
422 found = btrace_find_insn_by_number (&begin, btinfo, low);
424 error (_("Range out of bounds."));
426 found = btrace_find_insn_by_number (&end, btinfo, high);
429 /* Silently truncate the range. */
430 btrace_insn_end (&end, btinfo);
434 /* We want both begin and end to be inclusive. */
435 btrace_insn_next (&end, 1);
438 btrace_insn_history (uiout, &begin, &end, flags);
439 btrace_set_insn_history (btinfo, &begin, &end);
441 do_cleanups (uiout_cleanup);
444 /* The to_insn_history_from method of target record-btrace. */
447 record_btrace_insn_history_from (ULONGEST from, int size, int flags)
449 ULONGEST begin, end, context;
451 context = abs (size);
453 error (_("Bad record instruction-history-size."));
462 begin = from - context + 1;
467 end = from + context - 1;
469 /* Check for wrap-around. */
474 record_btrace_insn_history_range (begin, end, flags);
477 /* Print the instruction number range for a function call history line. */
480 btrace_call_history_insn_range (struct ui_out *uiout,
481 const struct btrace_function *bfun)
483 unsigned int begin, end, size;
485 size = VEC_length (btrace_insn_s, bfun->insn);
486 gdb_assert (size > 0);
488 begin = bfun->insn_offset;
489 end = begin + size - 1;
491 ui_out_field_uint (uiout, "insn begin", begin);
492 ui_out_text (uiout, ",");
493 ui_out_field_uint (uiout, "insn end", end);
496 /* Print the source line information for a function call history line. */
499 btrace_call_history_src_line (struct ui_out *uiout,
500 const struct btrace_function *bfun)
509 ui_out_field_string (uiout, "file",
510 symtab_to_filename_for_display (sym->symtab));
512 begin = bfun->lbegin;
518 ui_out_text (uiout, ":");
519 ui_out_field_int (uiout, "min line", begin);
524 ui_out_text (uiout, ",");
525 ui_out_field_int (uiout, "max line", end);
528 /* Get the name of a branch trace function. */
531 btrace_get_bfun_name (const struct btrace_function *bfun)
533 struct minimal_symbol *msym;
543 return SYMBOL_PRINT_NAME (sym);
544 else if (msym != NULL)
545 return SYMBOL_PRINT_NAME (msym);
550 /* Disassemble a section of the recorded function trace. */
553 btrace_call_history (struct ui_out *uiout,
554 const struct btrace_thread_info *btinfo,
555 const struct btrace_call_iterator *begin,
556 const struct btrace_call_iterator *end,
557 enum record_print_flag flags)
559 struct btrace_call_iterator it;
561 DEBUG ("ftrace (0x%x): [%u; %u)", flags, btrace_call_number (begin),
562 btrace_call_number (end));
564 for (it = *begin; btrace_call_cmp (&it, end) < 0; btrace_call_next (&it, 1))
566 const struct btrace_function *bfun;
567 struct minimal_symbol *msym;
570 bfun = btrace_call_get (&it);
574 /* Print the function index. */
575 ui_out_field_uint (uiout, "index", bfun->number);
576 ui_out_text (uiout, "\t");
578 if ((flags & RECORD_PRINT_INDENT_CALLS) != 0)
580 int level = bfun->level + btinfo->level, i;
582 for (i = 0; i < level; ++i)
583 ui_out_text (uiout, " ");
587 ui_out_field_string (uiout, "function", SYMBOL_PRINT_NAME (sym));
588 else if (msym != NULL)
589 ui_out_field_string (uiout, "function", SYMBOL_PRINT_NAME (msym));
590 else if (!ui_out_is_mi_like_p (uiout))
591 ui_out_field_string (uiout, "function", "??");
593 if ((flags & RECORD_PRINT_INSN_RANGE) != 0)
595 ui_out_text (uiout, _("\tinst "));
596 btrace_call_history_insn_range (uiout, bfun);
599 if ((flags & RECORD_PRINT_SRC_LINE) != 0)
601 ui_out_text (uiout, _("\tat "));
602 btrace_call_history_src_line (uiout, bfun);
605 ui_out_text (uiout, "\n");
609 /* The to_call_history method of target record-btrace. */
612 record_btrace_call_history (int size, int flags)
614 struct btrace_thread_info *btinfo;
615 struct btrace_call_history *history;
616 struct btrace_call_iterator begin, end;
617 struct cleanup *uiout_cleanup;
618 struct ui_out *uiout;
619 unsigned int context, covered;
621 uiout = current_uiout;
622 uiout_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout,
624 context = abs (size);
626 error (_("Bad record function-call-history-size."));
628 btinfo = require_btrace ();
629 history = btinfo->call_history;
632 struct btrace_insn_iterator *replay;
634 DEBUG ("call-history (0x%x): %d", flags, size);
636 /* If we're replaying, we start at the replay position. Otherwise, we
637 start at the tail of the trace. */
638 replay = btinfo->replay;
641 begin.function = replay->function;
642 begin.btinfo = btinfo;
645 btrace_call_end (&begin, btinfo);
647 /* We start from here and expand in the requested direction. Then we
648 expand in the other direction, as well, to fill up any remaining
653 /* We want the current position covered, as well. */
654 covered = btrace_call_next (&end, 1);
655 covered += btrace_call_prev (&begin, context - covered);
656 covered += btrace_call_next (&end, context - covered);
660 covered = btrace_call_next (&end, context);
661 covered += btrace_call_prev (&begin, context- covered);
666 begin = history->begin;
669 DEBUG ("call-history (0x%x): %d, prev: [%u; %u)", flags, size,
670 btrace_call_number (&begin), btrace_call_number (&end));
675 covered = btrace_call_prev (&begin, context);
680 covered = btrace_call_next (&end, context);
685 btrace_call_history (uiout, btinfo, &begin, &end, flags);
689 printf_unfiltered (_("At the start of the branch trace record.\n"));
691 printf_unfiltered (_("At the end of the branch trace record.\n"));
694 btrace_set_call_history (btinfo, &begin, &end);
695 do_cleanups (uiout_cleanup);
698 /* The to_call_history_range method of target record-btrace. */
701 record_btrace_call_history_range (ULONGEST from, ULONGEST to, int flags)
703 struct btrace_thread_info *btinfo;
704 struct btrace_call_history *history;
705 struct btrace_call_iterator begin, end;
706 struct cleanup *uiout_cleanup;
707 struct ui_out *uiout;
708 unsigned int low, high;
711 uiout = current_uiout;
712 uiout_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout,
717 DEBUG ("call-history (0x%x): [%u; %u)", flags, low, high);
719 /* Check for wrap-arounds. */
720 if (low != from || high != to)
721 error (_("Bad range."));
724 error (_("Bad range."));
726 btinfo = require_btrace ();
728 found = btrace_find_call_by_number (&begin, btinfo, low);
730 error (_("Range out of bounds."));
732 found = btrace_find_call_by_number (&end, btinfo, high);
735 /* Silently truncate the range. */
736 btrace_call_end (&end, btinfo);
740 /* We want both begin and end to be inclusive. */
741 btrace_call_next (&end, 1);
744 btrace_call_history (uiout, btinfo, &begin, &end, flags);
745 btrace_set_call_history (btinfo, &begin, &end);
747 do_cleanups (uiout_cleanup);
750 /* The to_call_history_from method of target record-btrace. */
753 record_btrace_call_history_from (ULONGEST from, int size, int flags)
755 ULONGEST begin, end, context;
757 context = abs (size);
759 error (_("Bad record function-call-history-size."));
768 begin = from - context + 1;
773 end = from + context - 1;
775 /* Check for wrap-around. */
780 record_btrace_call_history_range (begin, end, flags);
783 /* The to_record_is_replaying method of target record-btrace. */
786 record_btrace_is_replaying (void)
788 struct thread_info *tp;
791 if (btrace_is_replaying (tp))
797 /* The to_xfer_partial method of target record-btrace. */
800 record_btrace_xfer_partial (struct target_ops *ops, enum target_object object,
801 const char *annex, gdb_byte *readbuf,
802 const gdb_byte *writebuf, ULONGEST offset,
805 struct target_ops *t;
807 /* Filter out requests that don't make sense during replay. */
808 if (!record_btrace_allow_memory_access && record_btrace_is_replaying ())
812 case TARGET_OBJECT_MEMORY:
814 struct target_section *section;
816 /* We do not allow writing memory in general. */
817 if (writebuf != NULL)
818 return TARGET_XFER_E_UNAVAILABLE;
820 /* We allow reading readonly memory. */
821 section = target_section_by_addr (ops, offset);
824 /* Check if the section we found is readonly. */
825 if ((bfd_get_section_flags (section->the_bfd_section->owner,
826 section->the_bfd_section)
827 & SEC_READONLY) != 0)
829 /* Truncate the request to fit into this section. */
830 len = min (len, section->endaddr - offset);
835 return TARGET_XFER_E_UNAVAILABLE;
840 /* Forward the request. */
841 for (ops = ops->beneath; ops != NULL; ops = ops->beneath)
842 if (ops->to_xfer_partial != NULL)
843 return ops->to_xfer_partial (ops, object, annex, readbuf, writebuf,
846 return TARGET_XFER_E_UNAVAILABLE;
849 /* The to_insert_breakpoint method of target record-btrace. */
852 record_btrace_insert_breakpoint (struct target_ops *ops,
853 struct gdbarch *gdbarch,
854 struct bp_target_info *bp_tgt)
856 volatile struct gdb_exception except;
859 /* Inserting breakpoints requires accessing memory. Allow it for the
860 duration of this function. */
861 old = record_btrace_allow_memory_access;
862 record_btrace_allow_memory_access = 1;
865 TRY_CATCH (except, RETURN_MASK_ALL)
866 ret = forward_target_insert_breakpoint (ops->beneath, gdbarch, bp_tgt);
868 record_btrace_allow_memory_access = old;
870 if (except.reason < 0)
871 throw_exception (except);
876 /* The to_remove_breakpoint method of target record-btrace. */
879 record_btrace_remove_breakpoint (struct target_ops *ops,
880 struct gdbarch *gdbarch,
881 struct bp_target_info *bp_tgt)
883 volatile struct gdb_exception except;
886 /* Removing breakpoints requires accessing memory. Allow it for the
887 duration of this function. */
888 old = record_btrace_allow_memory_access;
889 record_btrace_allow_memory_access = 1;
892 TRY_CATCH (except, RETURN_MASK_ALL)
893 ret = forward_target_remove_breakpoint (ops->beneath, gdbarch, bp_tgt);
895 record_btrace_allow_memory_access = old;
897 if (except.reason < 0)
898 throw_exception (except);
903 /* The to_fetch_registers method of target record-btrace. */
906 record_btrace_fetch_registers (struct target_ops *ops,
907 struct regcache *regcache, int regno)
909 struct btrace_insn_iterator *replay;
910 struct thread_info *tp;
912 tp = find_thread_ptid (inferior_ptid);
913 gdb_assert (tp != NULL);
915 replay = tp->btrace.replay;
918 const struct btrace_insn *insn;
919 struct gdbarch *gdbarch;
922 gdbarch = get_regcache_arch (regcache);
923 pcreg = gdbarch_pc_regnum (gdbarch);
927 /* We can only provide the PC register. */
928 if (regno >= 0 && regno != pcreg)
931 insn = btrace_insn_get (replay);
932 gdb_assert (insn != NULL);
934 regcache_raw_supply (regcache, regno, &insn->pc);
938 struct target_ops *t;
940 for (t = ops->beneath; t != NULL; t = t->beneath)
941 if (t->to_fetch_registers != NULL)
943 t->to_fetch_registers (t, regcache, regno);
949 /* The to_store_registers method of target record-btrace. */
952 record_btrace_store_registers (struct target_ops *ops,
953 struct regcache *regcache, int regno)
955 struct target_ops *t;
957 if (record_btrace_is_replaying ())
958 error (_("This record target does not allow writing registers."));
960 gdb_assert (may_write_registers != 0);
962 for (t = ops->beneath; t != NULL; t = t->beneath)
963 if (t->to_store_registers != NULL)
965 t->to_store_registers (t, regcache, regno);
972 /* The to_prepare_to_store method of target record-btrace. */
975 record_btrace_prepare_to_store (struct target_ops *ops,
976 struct regcache *regcache)
978 struct target_ops *t;
980 if (record_btrace_is_replaying ())
983 for (t = ops->beneath; t != NULL; t = t->beneath)
984 if (t->to_prepare_to_store != NULL)
986 t->to_prepare_to_store (t, regcache);
991 /* The branch trace frame cache. */
993 struct btrace_frame_cache
996 struct thread_info *tp;
998 /* The frame info. */
999 struct frame_info *frame;
1001 /* The branch trace function segment. */
1002 const struct btrace_function *bfun;
1005 /* A struct btrace_frame_cache hash table indexed by NEXT. */
1007 static htab_t bfcache;
1009 /* hash_f for htab_create_alloc of bfcache. */
1012 bfcache_hash (const void *arg)
1014 const struct btrace_frame_cache *cache = arg;
1016 return htab_hash_pointer (cache->frame);
1019 /* eq_f for htab_create_alloc of bfcache. */
1022 bfcache_eq (const void *arg1, const void *arg2)
1024 const struct btrace_frame_cache *cache1 = arg1;
1025 const struct btrace_frame_cache *cache2 = arg2;
1027 return cache1->frame == cache2->frame;
1030 /* Create a new btrace frame cache. */
1032 static struct btrace_frame_cache *
1033 bfcache_new (struct frame_info *frame)
1035 struct btrace_frame_cache *cache;
1038 cache = FRAME_OBSTACK_ZALLOC (struct btrace_frame_cache);
1039 cache->frame = frame;
1041 slot = htab_find_slot (bfcache, cache, INSERT);
1042 gdb_assert (*slot == NULL);
1048 /* Extract the branch trace function from a branch trace frame. */
1050 static const struct btrace_function *
1051 btrace_get_frame_function (struct frame_info *frame)
1053 const struct btrace_frame_cache *cache;
1054 const struct btrace_function *bfun;
1055 struct btrace_frame_cache pattern;
1058 pattern.frame = frame;
1060 slot = htab_find_slot (bfcache, &pattern, NO_INSERT);
1068 /* Implement stop_reason method for record_btrace_frame_unwind. */
1070 static enum unwind_stop_reason
1071 record_btrace_frame_unwind_stop_reason (struct frame_info *this_frame,
1074 const struct btrace_frame_cache *cache;
1075 const struct btrace_function *bfun;
1077 cache = *this_cache;
1079 gdb_assert (bfun != NULL);
1081 if (bfun->up == NULL)
1082 return UNWIND_UNAVAILABLE;
1084 return UNWIND_NO_REASON;
1087 /* Implement this_id method for record_btrace_frame_unwind. */
1090 record_btrace_frame_this_id (struct frame_info *this_frame, void **this_cache,
1091 struct frame_id *this_id)
1093 const struct btrace_frame_cache *cache;
1094 const struct btrace_function *bfun;
1095 CORE_ADDR code, special;
1097 cache = *this_cache;
1100 gdb_assert (bfun != NULL);
1102 while (bfun->segment.prev != NULL)
1103 bfun = bfun->segment.prev;
1105 code = get_frame_func (this_frame);
1106 special = bfun->number;
1108 *this_id = frame_id_build_unavailable_stack_special (code, special);
1110 DEBUG ("[frame] %s id: (!stack, pc=%s, special=%s)",
1111 btrace_get_bfun_name (cache->bfun),
1112 core_addr_to_string_nz (this_id->code_addr),
1113 core_addr_to_string_nz (this_id->special_addr));
1116 /* Implement prev_register method for record_btrace_frame_unwind. */
1118 static struct value *
1119 record_btrace_frame_prev_register (struct frame_info *this_frame,
1123 const struct btrace_frame_cache *cache;
1124 const struct btrace_function *bfun, *caller;
1125 const struct btrace_insn *insn;
1126 struct gdbarch *gdbarch;
1130 gdbarch = get_frame_arch (this_frame);
1131 pcreg = gdbarch_pc_regnum (gdbarch);
1132 if (pcreg < 0 || regnum != pcreg)
1133 throw_error (NOT_AVAILABLE_ERROR,
1134 _("Registers are not available in btrace record history"));
1136 cache = *this_cache;
1138 gdb_assert (bfun != NULL);
1142 throw_error (NOT_AVAILABLE_ERROR,
1143 _("No caller in btrace record history"));
1145 if ((bfun->flags & BFUN_UP_LINKS_TO_RET) != 0)
1147 insn = VEC_index (btrace_insn_s, caller->insn, 0);
1152 insn = VEC_last (btrace_insn_s, caller->insn);
1155 pc += gdb_insn_length (gdbarch, pc);
1158 DEBUG ("[frame] unwound PC in %s on level %d: %s",
1159 btrace_get_bfun_name (bfun), bfun->level,
1160 core_addr_to_string_nz (pc));
1162 return frame_unwind_got_address (this_frame, regnum, pc);
1165 /* Implement sniffer method for record_btrace_frame_unwind. */
1168 record_btrace_frame_sniffer (const struct frame_unwind *self,
1169 struct frame_info *this_frame,
1172 const struct btrace_function *bfun;
1173 struct btrace_frame_cache *cache;
1174 struct thread_info *tp;
1175 struct frame_info *next;
1177 /* THIS_FRAME does not contain a reference to its thread. */
1178 tp = find_thread_ptid (inferior_ptid);
1179 gdb_assert (tp != NULL);
1182 next = get_next_frame (this_frame);
1185 const struct btrace_insn_iterator *replay;
1187 replay = tp->btrace.replay;
1189 bfun = replay->function;
1193 const struct btrace_function *callee;
1195 callee = btrace_get_frame_function (next);
1196 if (callee != NULL && (callee->flags & BFUN_UP_LINKS_TO_TAILCALL) == 0)
1203 DEBUG ("[frame] sniffed frame for %s on level %d",
1204 btrace_get_bfun_name (bfun), bfun->level);
1206 /* This is our frame. Initialize the frame cache. */
1207 cache = bfcache_new (this_frame);
1211 *this_cache = cache;
1215 /* Implement sniffer method for record_btrace_tailcall_frame_unwind. */
1218 record_btrace_tailcall_frame_sniffer (const struct frame_unwind *self,
1219 struct frame_info *this_frame,
1222 const struct btrace_function *bfun, *callee;
1223 struct btrace_frame_cache *cache;
1224 struct frame_info *next;
1226 next = get_next_frame (this_frame);
1230 callee = btrace_get_frame_function (next);
1234 if ((callee->flags & BFUN_UP_LINKS_TO_TAILCALL) == 0)
1241 DEBUG ("[frame] sniffed tailcall frame for %s on level %d",
1242 btrace_get_bfun_name (bfun), bfun->level);
1244 /* This is our frame. Initialize the frame cache. */
1245 cache = bfcache_new (this_frame);
1246 cache->tp = find_thread_ptid (inferior_ptid);
1249 *this_cache = cache;
1254 record_btrace_frame_dealloc_cache (struct frame_info *self, void *this_cache)
1256 struct btrace_frame_cache *cache;
1261 slot = htab_find_slot (bfcache, cache, NO_INSERT);
1262 gdb_assert (slot != NULL);
1264 htab_remove_elt (bfcache, cache);
1267 /* btrace recording does not store previous memory content, neither the stack
1268 frames content. Any unwinding would return errorneous results as the stack
1269 contents no longer matches the changed PC value restored from history.
1270 Therefore this unwinder reports any possibly unwound registers as
1273 const struct frame_unwind record_btrace_frame_unwind =
1276 record_btrace_frame_unwind_stop_reason,
1277 record_btrace_frame_this_id,
1278 record_btrace_frame_prev_register,
1280 record_btrace_frame_sniffer,
1281 record_btrace_frame_dealloc_cache
1284 const struct frame_unwind record_btrace_tailcall_frame_unwind =
1287 record_btrace_frame_unwind_stop_reason,
1288 record_btrace_frame_this_id,
1289 record_btrace_frame_prev_register,
1291 record_btrace_tailcall_frame_sniffer,
1292 record_btrace_frame_dealloc_cache
1295 /* The to_resume method of target record-btrace. */
1298 record_btrace_resume (struct target_ops *ops, ptid_t ptid, int step,
1299 enum gdb_signal signal)
1301 /* As long as we're not replaying, just forward the request. */
1302 if (!record_btrace_is_replaying ())
1304 for (ops = ops->beneath; ops != NULL; ops = ops->beneath)
1305 if (ops->to_resume != NULL)
1306 return ops->to_resume (ops, ptid, step, signal);
1308 error (_("Cannot find target for stepping."));
1311 error (_("You can't do this from here. Do 'record goto end', first."));
1314 /* The to_wait method of target record-btrace. */
1317 record_btrace_wait (struct target_ops *ops, ptid_t ptid,
1318 struct target_waitstatus *status, int options)
1320 /* As long as we're not replaying, just forward the request. */
1321 if (!record_btrace_is_replaying ())
1323 for (ops = ops->beneath; ops != NULL; ops = ops->beneath)
1324 if (ops->to_wait != NULL)
1325 return ops->to_wait (ops, ptid, status, options);
1327 error (_("Cannot find target for waiting."));
1330 error (_("You can't do this from here. Do 'record goto end', first."));
1333 /* The to_find_new_threads method of target record-btrace. */
1336 record_btrace_find_new_threads (struct target_ops *ops)
1338 /* Don't expect new threads if we're replaying. */
1339 if (record_btrace_is_replaying ())
1342 /* Forward the request. */
1343 for (ops = ops->beneath; ops != NULL; ops = ops->beneath)
1344 if (ops->to_find_new_threads != NULL)
1346 ops->to_find_new_threads (ops);
1351 /* The to_thread_alive method of target record-btrace. */
1354 record_btrace_thread_alive (struct target_ops *ops, ptid_t ptid)
1356 /* We don't add or remove threads during replay. */
1357 if (record_btrace_is_replaying ())
1358 return find_thread_ptid (ptid) != NULL;
1360 /* Forward the request. */
1361 for (ops = ops->beneath; ops != NULL; ops = ops->beneath)
1362 if (ops->to_thread_alive != NULL)
1363 return ops->to_thread_alive (ops, ptid);
1368 /* Set the replay branch trace instruction iterator. If IT is NULL, replay
1372 record_btrace_set_replay (struct thread_info *tp,
1373 const struct btrace_insn_iterator *it)
1375 struct btrace_thread_info *btinfo;
1377 btinfo = &tp->btrace;
1379 if (it == NULL || it->function == NULL)
1381 if (btinfo->replay == NULL)
1384 xfree (btinfo->replay);
1385 btinfo->replay = NULL;
1389 if (btinfo->replay == NULL)
1390 btinfo->replay = xmalloc (sizeof (*btinfo->replay));
1391 else if (btrace_insn_cmp (btinfo->replay, it) == 0)
1394 *btinfo->replay = *it;
1397 /* Clear the function call and instruction histories so we start anew
1398 from the new replay position. */
1399 xfree (btinfo->insn_history);
1400 xfree (btinfo->call_history);
1402 btinfo->insn_history = NULL;
1403 btinfo->call_history = NULL;
1405 registers_changed_ptid (tp->ptid);
1408 /* The to_goto_record_begin method of target record-btrace. */
1411 record_btrace_goto_begin (void)
1413 struct thread_info *tp;
1414 struct btrace_insn_iterator begin;
1416 tp = require_btrace_thread ();
1418 btrace_insn_begin (&begin, &tp->btrace);
1419 record_btrace_set_replay (tp, &begin);
1421 print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
1424 /* The to_goto_record_end method of target record-btrace. */
1427 record_btrace_goto_end (void)
1429 struct thread_info *tp;
1431 tp = require_btrace_thread ();
1433 record_btrace_set_replay (tp, NULL);
1435 print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
1438 /* The to_goto_record method of target record-btrace. */
1441 record_btrace_goto (ULONGEST insn)
1443 struct thread_info *tp;
1444 struct btrace_insn_iterator it;
1445 unsigned int number;
1450 /* Check for wrap-arounds. */
1452 error (_("Instruction number out of range."));
1454 tp = require_btrace_thread ();
1456 found = btrace_find_insn_by_number (&it, &tp->btrace, number);
1458 error (_("No such instruction."));
1460 record_btrace_set_replay (tp, &it);
1462 print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
1465 /* Initialize the record-btrace target ops. */
1468 init_record_btrace_ops (void)
1470 struct target_ops *ops;
1472 ops = &record_btrace_ops;
1473 ops->to_shortname = "record-btrace";
1474 ops->to_longname = "Branch tracing target";
1475 ops->to_doc = "Collect control-flow trace and provide the execution history.";
1476 ops->to_open = record_btrace_open;
1477 ops->to_close = record_btrace_close;
1478 ops->to_detach = record_detach;
1479 ops->to_disconnect = record_disconnect;
1480 ops->to_mourn_inferior = record_mourn_inferior;
1481 ops->to_kill = record_kill;
1482 ops->to_create_inferior = find_default_create_inferior;
1483 ops->to_stop_recording = record_btrace_stop_recording;
1484 ops->to_info_record = record_btrace_info;
1485 ops->to_insn_history = record_btrace_insn_history;
1486 ops->to_insn_history_from = record_btrace_insn_history_from;
1487 ops->to_insn_history_range = record_btrace_insn_history_range;
1488 ops->to_call_history = record_btrace_call_history;
1489 ops->to_call_history_from = record_btrace_call_history_from;
1490 ops->to_call_history_range = record_btrace_call_history_range;
1491 ops->to_record_is_replaying = record_btrace_is_replaying;
1492 ops->to_xfer_partial = record_btrace_xfer_partial;
1493 ops->to_remove_breakpoint = record_btrace_remove_breakpoint;
1494 ops->to_insert_breakpoint = record_btrace_insert_breakpoint;
1495 ops->to_fetch_registers = record_btrace_fetch_registers;
1496 ops->to_store_registers = record_btrace_store_registers;
1497 ops->to_prepare_to_store = record_btrace_prepare_to_store;
1498 ops->to_get_unwinder = &record_btrace_frame_unwind;
1499 ops->to_get_tailcall_unwinder = &record_btrace_tailcall_frame_unwind;
1500 ops->to_resume = record_btrace_resume;
1501 ops->to_wait = record_btrace_wait;
1502 ops->to_find_new_threads = record_btrace_find_new_threads;
1503 ops->to_thread_alive = record_btrace_thread_alive;
1504 ops->to_goto_record_begin = record_btrace_goto_begin;
1505 ops->to_goto_record_end = record_btrace_goto_end;
1506 ops->to_goto_record = record_btrace_goto;
1507 ops->to_stratum = record_stratum;
1508 ops->to_magic = OPS_MAGIC;
1511 /* Alias for "target record". */
1514 cmd_record_btrace_start (char *args, int from_tty)
1516 if (args != NULL && *args != 0)
1517 error (_("Invalid argument."));
1519 execute_command ("target record-btrace", from_tty);
1522 void _initialize_record_btrace (void);
1524 /* Initialize btrace commands. */
1527 _initialize_record_btrace (void)
1529 add_cmd ("btrace", class_obscure, cmd_record_btrace_start,
1530 _("Start branch trace recording."),
1532 add_alias_cmd ("b", "btrace", class_obscure, 1, &record_cmdlist);
1534 init_record_btrace_ops ();
1535 add_target (&record_btrace_ops);
1537 bfcache = htab_create_alloc (50, bfcache_hash, bfcache_eq, NULL,