1 /* Branch trace support for GDB, the GNU debugger.
3 Copyright (C) 2013-2015 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 "cli/cli-utils.h"
33 #include "filenames.h"
35 #include "frame-unwind.h"
38 #include "event-loop.h"
42 /* The target_ops of record-btrace. */
43 static struct target_ops record_btrace_ops
;
45 /* A new thread observer enabling branch tracing for the new thread. */
46 static struct observer
*record_btrace_thread_observer
;
48 /* Memory access types used in set/show record btrace replay-memory-access. */
49 static const char replay_memory_access_read_only
[] = "read-only";
50 static const char replay_memory_access_read_write
[] = "read-write";
51 static const char *const replay_memory_access_types
[] =
53 replay_memory_access_read_only
,
54 replay_memory_access_read_write
,
58 /* The currently allowed replay memory access type. */
59 static const char *replay_memory_access
= replay_memory_access_read_only
;
61 /* Command lists for "set/show record btrace". */
62 static struct cmd_list_element
*set_record_btrace_cmdlist
;
63 static struct cmd_list_element
*show_record_btrace_cmdlist
;
65 /* The execution direction of the last resume we got. See record-full.c. */
66 static enum exec_direction_kind record_btrace_resume_exec_dir
= EXEC_FORWARD
;
68 /* The async event handler for reverse/replay execution. */
69 static struct async_event_handler
*record_btrace_async_inferior_event_handler
;
71 /* A flag indicating that we are currently generating a core file. */
72 static int record_btrace_generating_corefile
;
74 /* The current branch trace configuration. */
75 static struct btrace_config record_btrace_conf
;
77 /* Command list for "record btrace". */
78 static struct cmd_list_element
*record_btrace_cmdlist
;
80 /* Command lists for "set/show record btrace bts". */
81 static struct cmd_list_element
*set_record_btrace_bts_cmdlist
;
82 static struct cmd_list_element
*show_record_btrace_bts_cmdlist
;
84 /* Command lists for "set/show record btrace pt". */
85 static struct cmd_list_element
*set_record_btrace_pt_cmdlist
;
86 static struct cmd_list_element
*show_record_btrace_pt_cmdlist
;
88 /* Print a record-btrace debug message. Use do ... while (0) to avoid
89 ambiguities when used in if statements. */
91 #define DEBUG(msg, args...) \
94 if (record_debug != 0) \
95 fprintf_unfiltered (gdb_stdlog, \
96 "[record-btrace] " msg "\n", ##args); \
101 /* Update the branch trace for the current thread and return a pointer to its
104 Throws an error if there is no thread or no trace. This function never
107 static struct thread_info
*
108 require_btrace_thread (void)
110 struct thread_info
*tp
;
114 tp
= find_thread_ptid (inferior_ptid
);
116 error (_("No thread."));
120 if (btrace_is_empty (tp
))
121 error (_("No trace."));
126 /* Update the branch trace for the current thread and return a pointer to its
127 branch trace information struct.
129 Throws an error if there is no thread or no trace. This function never
132 static struct btrace_thread_info
*
133 require_btrace (void)
135 struct thread_info
*tp
;
137 tp
= require_btrace_thread ();
142 /* Enable branch tracing for one thread. Warn on errors. */
145 record_btrace_enable_warn (struct thread_info
*tp
)
149 btrace_enable (tp
, &record_btrace_conf
);
151 CATCH (error
, RETURN_MASK_ERROR
)
153 warning ("%s", error
.message
);
158 /* Callback function to disable branch tracing for one thread. */
161 record_btrace_disable_callback (void *arg
)
163 struct thread_info
*tp
;
170 /* Enable automatic tracing of new threads. */
173 record_btrace_auto_enable (void)
175 DEBUG ("attach thread observer");
177 record_btrace_thread_observer
178 = observer_attach_new_thread (record_btrace_enable_warn
);
181 /* Disable automatic tracing of new threads. */
184 record_btrace_auto_disable (void)
186 /* The observer may have been detached, already. */
187 if (record_btrace_thread_observer
== NULL
)
190 DEBUG ("detach thread observer");
192 observer_detach_new_thread (record_btrace_thread_observer
);
193 record_btrace_thread_observer
= NULL
;
196 /* The record-btrace async event handler function. */
199 record_btrace_handle_async_inferior_event (gdb_client_data data
)
201 inferior_event_handler (INF_REG_EVENT
, NULL
);
204 /* The to_open method of target record-btrace. */
207 record_btrace_open (const char *args
, int from_tty
)
209 struct cleanup
*disable_chain
;
210 struct thread_info
*tp
;
216 if (!target_has_execution
)
217 error (_("The program is not being run."));
219 gdb_assert (record_btrace_thread_observer
== NULL
);
221 disable_chain
= make_cleanup (null_cleanup
, NULL
);
222 ALL_NON_EXITED_THREADS (tp
)
223 if (args
== NULL
|| *args
== 0 || number_is_in_list (args
, tp
->num
))
225 btrace_enable (tp
, &record_btrace_conf
);
227 make_cleanup (record_btrace_disable_callback
, tp
);
230 record_btrace_auto_enable ();
232 push_target (&record_btrace_ops
);
234 record_btrace_async_inferior_event_handler
235 = create_async_event_handler (record_btrace_handle_async_inferior_event
,
237 record_btrace_generating_corefile
= 0;
239 observer_notify_record_changed (current_inferior (), 1);
241 discard_cleanups (disable_chain
);
244 /* The to_stop_recording method of target record-btrace. */
247 record_btrace_stop_recording (struct target_ops
*self
)
249 struct thread_info
*tp
;
251 DEBUG ("stop recording");
253 record_btrace_auto_disable ();
255 ALL_NON_EXITED_THREADS (tp
)
256 if (tp
->btrace
.target
!= NULL
)
260 /* The to_close method of target record-btrace. */
263 record_btrace_close (struct target_ops
*self
)
265 struct thread_info
*tp
;
267 if (record_btrace_async_inferior_event_handler
!= NULL
)
268 delete_async_event_handler (&record_btrace_async_inferior_event_handler
);
270 /* Make sure automatic recording gets disabled even if we did not stop
271 recording before closing the record-btrace target. */
272 record_btrace_auto_disable ();
274 /* We should have already stopped recording.
275 Tear down btrace in case we have not. */
276 ALL_NON_EXITED_THREADS (tp
)
277 btrace_teardown (tp
);
280 /* The to_async method of target record-btrace. */
283 record_btrace_async (struct target_ops
*ops
, int enable
)
286 mark_async_event_handler (record_btrace_async_inferior_event_handler
);
288 clear_async_event_handler (record_btrace_async_inferior_event_handler
);
290 ops
->beneath
->to_async (ops
->beneath
, enable
);
293 /* Adjusts the size and returns a human readable size suffix. */
296 record_btrace_adjust_size (unsigned int *size
)
302 if ((sz
& ((1u << 30) - 1)) == 0)
307 else if ((sz
& ((1u << 20) - 1)) == 0)
312 else if ((sz
& ((1u << 10) - 1)) == 0)
321 /* Print a BTS configuration. */
324 record_btrace_print_bts_conf (const struct btrace_config_bts
*conf
)
332 suffix
= record_btrace_adjust_size (&size
);
333 printf_unfiltered (_("Buffer size: %u%s.\n"), size
, suffix
);
337 /* Print an Intel(R) Processor Trace configuration. */
340 record_btrace_print_pt_conf (const struct btrace_config_pt
*conf
)
348 suffix
= record_btrace_adjust_size (&size
);
349 printf_unfiltered (_("Buffer size: %u%s.\n"), size
, suffix
);
353 /* Print a branch tracing configuration. */
356 record_btrace_print_conf (const struct btrace_config
*conf
)
358 printf_unfiltered (_("Recording format: %s.\n"),
359 btrace_format_string (conf
->format
));
361 switch (conf
->format
)
363 case BTRACE_FORMAT_NONE
:
366 case BTRACE_FORMAT_BTS
:
367 record_btrace_print_bts_conf (&conf
->bts
);
370 case BTRACE_FORMAT_PT
:
371 record_btrace_print_pt_conf (&conf
->pt
);
375 internal_error (__FILE__
, __LINE__
, _("Unkown branch trace format."));
378 /* The to_info_record method of target record-btrace. */
381 record_btrace_info (struct target_ops
*self
)
383 struct btrace_thread_info
*btinfo
;
384 const struct btrace_config
*conf
;
385 struct thread_info
*tp
;
386 unsigned int insns
, calls
, gaps
;
390 tp
= find_thread_ptid (inferior_ptid
);
392 error (_("No thread."));
394 btinfo
= &tp
->btrace
;
396 conf
= btrace_conf (btinfo
);
398 record_btrace_print_conf (conf
);
406 if (!btrace_is_empty (tp
))
408 struct btrace_call_iterator call
;
409 struct btrace_insn_iterator insn
;
411 btrace_call_end (&call
, btinfo
);
412 btrace_call_prev (&call
, 1);
413 calls
= btrace_call_number (&call
);
415 btrace_insn_end (&insn
, btinfo
);
417 insns
= btrace_insn_number (&insn
);
420 /* The last instruction does not really belong to the trace. */
427 /* Skip gaps at the end. */
430 steps
= btrace_insn_prev (&insn
, 1);
434 insns
= btrace_insn_number (&insn
);
439 gaps
= btinfo
->ngaps
;
442 printf_unfiltered (_("Recorded %u instructions in %u functions (%u gaps) "
443 "for thread %d (%s).\n"), insns
, calls
, gaps
,
444 tp
->num
, target_pid_to_str (tp
->ptid
));
446 if (btrace_is_replaying (tp
))
447 printf_unfiltered (_("Replay in progress. At instruction %u.\n"),
448 btrace_insn_number (btinfo
->replay
));
451 /* Print a decode error. */
454 btrace_ui_out_decode_error (struct ui_out
*uiout
, int errcode
,
455 enum btrace_format format
)
460 errstr
= _("unknown");
468 case BTRACE_FORMAT_BTS
:
474 case BDE_BTS_OVERFLOW
:
475 errstr
= _("instruction overflow");
478 case BDE_BTS_INSN_SIZE
:
479 errstr
= _("unknown instruction");
484 #if defined (HAVE_LIBIPT)
485 case BTRACE_FORMAT_PT
:
488 case BDE_PT_USER_QUIT
:
490 errstr
= _("trace decode cancelled");
493 case BDE_PT_DISABLED
:
495 errstr
= _("disabled");
498 case BDE_PT_OVERFLOW
:
500 errstr
= _("overflow");
505 errstr
= pt_errstr (pt_errcode (errcode
));
509 #endif /* defined (HAVE_LIBIPT) */
512 ui_out_text (uiout
, _("["));
515 ui_out_text (uiout
, _("decode error ("));
516 ui_out_field_int (uiout
, "errcode", errcode
);
517 ui_out_text (uiout
, _("): "));
519 ui_out_text (uiout
, errstr
);
520 ui_out_text (uiout
, _("]\n"));
523 /* Print an unsigned int. */
526 ui_out_field_uint (struct ui_out
*uiout
, const char *fld
, unsigned int val
)
528 ui_out_field_fmt (uiout
, fld
, "%u", val
);
531 /* Disassemble a section of the recorded instruction trace. */
534 btrace_insn_history (struct ui_out
*uiout
,
535 const struct btrace_thread_info
*btinfo
,
536 const struct btrace_insn_iterator
*begin
,
537 const struct btrace_insn_iterator
*end
, int flags
)
539 struct gdbarch
*gdbarch
;
540 struct btrace_insn_iterator it
;
542 DEBUG ("itrace (0x%x): [%u; %u)", flags
, btrace_insn_number (begin
),
543 btrace_insn_number (end
));
545 gdbarch
= target_gdbarch ();
547 for (it
= *begin
; btrace_insn_cmp (&it
, end
) != 0; btrace_insn_next (&it
, 1))
549 const struct btrace_insn
*insn
;
551 insn
= btrace_insn_get (&it
);
553 /* A NULL instruction indicates a gap in the trace. */
556 const struct btrace_config
*conf
;
558 conf
= btrace_conf (btinfo
);
560 /* We have trace so we must have a configuration. */
561 gdb_assert (conf
!= NULL
);
563 btrace_ui_out_decode_error (uiout
, it
.function
->errcode
,
570 /* We may add a speculation prefix later. We use the same space
571 that is used for the pc prefix. */
572 if ((flags
& DISASSEMBLY_OMIT_PC
) == 0)
573 strncpy (prefix
, pc_prefix (insn
->pc
), 3);
582 /* Print the instruction index. */
583 ui_out_field_uint (uiout
, "index", btrace_insn_number (&it
));
584 ui_out_text (uiout
, "\t");
586 /* Indicate speculative execution by a leading '?'. */
587 if ((insn
->flags
& BTRACE_INSN_FLAG_SPECULATIVE
) != 0)
590 /* Print the prefix; we tell gdb_disassembly below to omit it. */
591 ui_out_field_fmt (uiout
, "prefix", "%s", prefix
);
593 /* Disassembly with '/m' flag may not produce the expected result.
595 gdb_disassembly (gdbarch
, uiout
, NULL
, flags
| DISASSEMBLY_OMIT_PC
,
596 1, insn
->pc
, insn
->pc
+ 1);
601 /* The to_insn_history method of target record-btrace. */
604 record_btrace_insn_history (struct target_ops
*self
, int size
, int flags
)
606 struct btrace_thread_info
*btinfo
;
607 struct btrace_insn_history
*history
;
608 struct btrace_insn_iterator begin
, end
;
609 struct cleanup
*uiout_cleanup
;
610 struct ui_out
*uiout
;
611 unsigned int context
, covered
;
613 uiout
= current_uiout
;
614 uiout_cleanup
= make_cleanup_ui_out_tuple_begin_end (uiout
,
616 context
= abs (size
);
618 error (_("Bad record instruction-history-size."));
620 btinfo
= require_btrace ();
621 history
= btinfo
->insn_history
;
624 struct btrace_insn_iterator
*replay
;
626 DEBUG ("insn-history (0x%x): %d", flags
, size
);
628 /* If we're replaying, we start at the replay position. Otherwise, we
629 start at the tail of the trace. */
630 replay
= btinfo
->replay
;
634 btrace_insn_end (&begin
, btinfo
);
636 /* We start from here and expand in the requested direction. Then we
637 expand in the other direction, as well, to fill up any remaining
642 /* We want the current position covered, as well. */
643 covered
= btrace_insn_next (&end
, 1);
644 covered
+= btrace_insn_prev (&begin
, context
- covered
);
645 covered
+= btrace_insn_next (&end
, context
- covered
);
649 covered
= btrace_insn_next (&end
, context
);
650 covered
+= btrace_insn_prev (&begin
, context
- covered
);
655 begin
= history
->begin
;
658 DEBUG ("insn-history (0x%x): %d, prev: [%u; %u)", flags
, size
,
659 btrace_insn_number (&begin
), btrace_insn_number (&end
));
664 covered
= btrace_insn_prev (&begin
, context
);
669 covered
= btrace_insn_next (&end
, context
);
674 btrace_insn_history (uiout
, btinfo
, &begin
, &end
, flags
);
678 printf_unfiltered (_("At the start of the branch trace record.\n"));
680 printf_unfiltered (_("At the end of the branch trace record.\n"));
683 btrace_set_insn_history (btinfo
, &begin
, &end
);
684 do_cleanups (uiout_cleanup
);
687 /* The to_insn_history_range method of target record-btrace. */
690 record_btrace_insn_history_range (struct target_ops
*self
,
691 ULONGEST from
, ULONGEST to
, int flags
)
693 struct btrace_thread_info
*btinfo
;
694 struct btrace_insn_history
*history
;
695 struct btrace_insn_iterator begin
, end
;
696 struct cleanup
*uiout_cleanup
;
697 struct ui_out
*uiout
;
698 unsigned int low
, high
;
701 uiout
= current_uiout
;
702 uiout_cleanup
= make_cleanup_ui_out_tuple_begin_end (uiout
,
707 DEBUG ("insn-history (0x%x): [%u; %u)", flags
, low
, high
);
709 /* Check for wrap-arounds. */
710 if (low
!= from
|| high
!= to
)
711 error (_("Bad range."));
714 error (_("Bad range."));
716 btinfo
= require_btrace ();
718 found
= btrace_find_insn_by_number (&begin
, btinfo
, low
);
720 error (_("Range out of bounds."));
722 found
= btrace_find_insn_by_number (&end
, btinfo
, high
);
725 /* Silently truncate the range. */
726 btrace_insn_end (&end
, btinfo
);
730 /* We want both begin and end to be inclusive. */
731 btrace_insn_next (&end
, 1);
734 btrace_insn_history (uiout
, btinfo
, &begin
, &end
, flags
);
735 btrace_set_insn_history (btinfo
, &begin
, &end
);
737 do_cleanups (uiout_cleanup
);
740 /* The to_insn_history_from method of target record-btrace. */
743 record_btrace_insn_history_from (struct target_ops
*self
,
744 ULONGEST from
, int size
, int flags
)
746 ULONGEST begin
, end
, context
;
748 context
= abs (size
);
750 error (_("Bad record instruction-history-size."));
759 begin
= from
- context
+ 1;
764 end
= from
+ context
- 1;
766 /* Check for wrap-around. */
771 record_btrace_insn_history_range (self
, begin
, end
, flags
);
774 /* Print the instruction number range for a function call history line. */
777 btrace_call_history_insn_range (struct ui_out
*uiout
,
778 const struct btrace_function
*bfun
)
780 unsigned int begin
, end
, size
;
782 size
= VEC_length (btrace_insn_s
, bfun
->insn
);
783 gdb_assert (size
> 0);
785 begin
= bfun
->insn_offset
;
786 end
= begin
+ size
- 1;
788 ui_out_field_uint (uiout
, "insn begin", begin
);
789 ui_out_text (uiout
, ",");
790 ui_out_field_uint (uiout
, "insn end", end
);
793 /* Compute the lowest and highest source line for the instructions in BFUN
794 and return them in PBEGIN and PEND.
795 Ignore instructions that can't be mapped to BFUN, e.g. instructions that
796 result from inlining or macro expansion. */
799 btrace_compute_src_line_range (const struct btrace_function
*bfun
,
800 int *pbegin
, int *pend
)
802 struct btrace_insn
*insn
;
803 struct symtab
*symtab
;
815 symtab
= symbol_symtab (sym
);
817 for (idx
= 0; VEC_iterate (btrace_insn_s
, bfun
->insn
, idx
, insn
); ++idx
)
819 struct symtab_and_line sal
;
821 sal
= find_pc_line (insn
->pc
, 0);
822 if (sal
.symtab
!= symtab
|| sal
.line
== 0)
825 begin
= min (begin
, sal
.line
);
826 end
= max (end
, sal
.line
);
834 /* Print the source line information for a function call history line. */
837 btrace_call_history_src_line (struct ui_out
*uiout
,
838 const struct btrace_function
*bfun
)
847 ui_out_field_string (uiout
, "file",
848 symtab_to_filename_for_display (symbol_symtab (sym
)));
850 btrace_compute_src_line_range (bfun
, &begin
, &end
);
854 ui_out_text (uiout
, ":");
855 ui_out_field_int (uiout
, "min line", begin
);
860 ui_out_text (uiout
, ",");
861 ui_out_field_int (uiout
, "max line", end
);
864 /* Get the name of a branch trace function. */
867 btrace_get_bfun_name (const struct btrace_function
*bfun
)
869 struct minimal_symbol
*msym
;
879 return SYMBOL_PRINT_NAME (sym
);
880 else if (msym
!= NULL
)
881 return MSYMBOL_PRINT_NAME (msym
);
886 /* Disassemble a section of the recorded function trace. */
889 btrace_call_history (struct ui_out
*uiout
,
890 const struct btrace_thread_info
*btinfo
,
891 const struct btrace_call_iterator
*begin
,
892 const struct btrace_call_iterator
*end
,
893 enum record_print_flag flags
)
895 struct btrace_call_iterator it
;
897 DEBUG ("ftrace (0x%x): [%u; %u)", flags
, btrace_call_number (begin
),
898 btrace_call_number (end
));
900 for (it
= *begin
; btrace_call_cmp (&it
, end
) < 0; btrace_call_next (&it
, 1))
902 const struct btrace_function
*bfun
;
903 struct minimal_symbol
*msym
;
906 bfun
= btrace_call_get (&it
);
910 /* Print the function index. */
911 ui_out_field_uint (uiout
, "index", bfun
->number
);
912 ui_out_text (uiout
, "\t");
914 /* Indicate gaps in the trace. */
915 if (bfun
->errcode
!= 0)
917 const struct btrace_config
*conf
;
919 conf
= btrace_conf (btinfo
);
921 /* We have trace so we must have a configuration. */
922 gdb_assert (conf
!= NULL
);
924 btrace_ui_out_decode_error (uiout
, bfun
->errcode
, conf
->format
);
929 if ((flags
& RECORD_PRINT_INDENT_CALLS
) != 0)
931 int level
= bfun
->level
+ btinfo
->level
, i
;
933 for (i
= 0; i
< level
; ++i
)
934 ui_out_text (uiout
, " ");
938 ui_out_field_string (uiout
, "function", SYMBOL_PRINT_NAME (sym
));
939 else if (msym
!= NULL
)
940 ui_out_field_string (uiout
, "function", MSYMBOL_PRINT_NAME (msym
));
941 else if (!ui_out_is_mi_like_p (uiout
))
942 ui_out_field_string (uiout
, "function", "??");
944 if ((flags
& RECORD_PRINT_INSN_RANGE
) != 0)
946 ui_out_text (uiout
, _("\tinst "));
947 btrace_call_history_insn_range (uiout
, bfun
);
950 if ((flags
& RECORD_PRINT_SRC_LINE
) != 0)
952 ui_out_text (uiout
, _("\tat "));
953 btrace_call_history_src_line (uiout
, bfun
);
956 ui_out_text (uiout
, "\n");
960 /* The to_call_history method of target record-btrace. */
963 record_btrace_call_history (struct target_ops
*self
, int size
, int flags
)
965 struct btrace_thread_info
*btinfo
;
966 struct btrace_call_history
*history
;
967 struct btrace_call_iterator begin
, end
;
968 struct cleanup
*uiout_cleanup
;
969 struct ui_out
*uiout
;
970 unsigned int context
, covered
;
972 uiout
= current_uiout
;
973 uiout_cleanup
= make_cleanup_ui_out_tuple_begin_end (uiout
,
975 context
= abs (size
);
977 error (_("Bad record function-call-history-size."));
979 btinfo
= require_btrace ();
980 history
= btinfo
->call_history
;
983 struct btrace_insn_iterator
*replay
;
985 DEBUG ("call-history (0x%x): %d", flags
, size
);
987 /* If we're replaying, we start at the replay position. Otherwise, we
988 start at the tail of the trace. */
989 replay
= btinfo
->replay
;
992 begin
.function
= replay
->function
;
993 begin
.btinfo
= btinfo
;
996 btrace_call_end (&begin
, btinfo
);
998 /* We start from here and expand in the requested direction. Then we
999 expand in the other direction, as well, to fill up any remaining
1004 /* We want the current position covered, as well. */
1005 covered
= btrace_call_next (&end
, 1);
1006 covered
+= btrace_call_prev (&begin
, context
- covered
);
1007 covered
+= btrace_call_next (&end
, context
- covered
);
1011 covered
= btrace_call_next (&end
, context
);
1012 covered
+= btrace_call_prev (&begin
, context
- covered
);
1017 begin
= history
->begin
;
1020 DEBUG ("call-history (0x%x): %d, prev: [%u; %u)", flags
, size
,
1021 btrace_call_number (&begin
), btrace_call_number (&end
));
1026 covered
= btrace_call_prev (&begin
, context
);
1031 covered
= btrace_call_next (&end
, context
);
1036 btrace_call_history (uiout
, btinfo
, &begin
, &end
, flags
);
1040 printf_unfiltered (_("At the start of the branch trace record.\n"));
1042 printf_unfiltered (_("At the end of the branch trace record.\n"));
1045 btrace_set_call_history (btinfo
, &begin
, &end
);
1046 do_cleanups (uiout_cleanup
);
1049 /* The to_call_history_range method of target record-btrace. */
1052 record_btrace_call_history_range (struct target_ops
*self
,
1053 ULONGEST from
, ULONGEST to
, int flags
)
1055 struct btrace_thread_info
*btinfo
;
1056 struct btrace_call_history
*history
;
1057 struct btrace_call_iterator begin
, end
;
1058 struct cleanup
*uiout_cleanup
;
1059 struct ui_out
*uiout
;
1060 unsigned int low
, high
;
1063 uiout
= current_uiout
;
1064 uiout_cleanup
= make_cleanup_ui_out_tuple_begin_end (uiout
,
1069 DEBUG ("call-history (0x%x): [%u; %u)", flags
, low
, high
);
1071 /* Check for wrap-arounds. */
1072 if (low
!= from
|| high
!= to
)
1073 error (_("Bad range."));
1076 error (_("Bad range."));
1078 btinfo
= require_btrace ();
1080 found
= btrace_find_call_by_number (&begin
, btinfo
, low
);
1082 error (_("Range out of bounds."));
1084 found
= btrace_find_call_by_number (&end
, btinfo
, high
);
1087 /* Silently truncate the range. */
1088 btrace_call_end (&end
, btinfo
);
1092 /* We want both begin and end to be inclusive. */
1093 btrace_call_next (&end
, 1);
1096 btrace_call_history (uiout
, btinfo
, &begin
, &end
, flags
);
1097 btrace_set_call_history (btinfo
, &begin
, &end
);
1099 do_cleanups (uiout_cleanup
);
1102 /* The to_call_history_from method of target record-btrace. */
1105 record_btrace_call_history_from (struct target_ops
*self
,
1106 ULONGEST from
, int size
, int flags
)
1108 ULONGEST begin
, end
, context
;
1110 context
= abs (size
);
1112 error (_("Bad record function-call-history-size."));
1121 begin
= from
- context
+ 1;
1126 end
= from
+ context
- 1;
1128 /* Check for wrap-around. */
1133 record_btrace_call_history_range (self
, begin
, end
, flags
);
1136 /* The to_record_is_replaying method of target record-btrace. */
1139 record_btrace_is_replaying (struct target_ops
*self
, ptid_t ptid
)
1141 struct thread_info
*tp
;
1143 ALL_NON_EXITED_THREADS (tp
)
1144 if (ptid_match (tp
->ptid
, ptid
) && btrace_is_replaying (tp
))
1150 /* The to_record_will_replay method of target record-btrace. */
1153 record_btrace_will_replay (struct target_ops
*self
, ptid_t ptid
, int dir
)
1155 return dir
== EXEC_REVERSE
|| record_btrace_is_replaying (self
, ptid
);
1158 /* The to_xfer_partial method of target record-btrace. */
1160 static enum target_xfer_status
1161 record_btrace_xfer_partial (struct target_ops
*ops
, enum target_object object
,
1162 const char *annex
, gdb_byte
*readbuf
,
1163 const gdb_byte
*writebuf
, ULONGEST offset
,
1164 ULONGEST len
, ULONGEST
*xfered_len
)
1166 struct target_ops
*t
;
1168 /* Filter out requests that don't make sense during replay. */
1169 if (replay_memory_access
== replay_memory_access_read_only
1170 && !record_btrace_generating_corefile
1171 && record_btrace_is_replaying (ops
, inferior_ptid
))
1175 case TARGET_OBJECT_MEMORY
:
1177 struct target_section
*section
;
1179 /* We do not allow writing memory in general. */
1180 if (writebuf
!= NULL
)
1183 return TARGET_XFER_UNAVAILABLE
;
1186 /* We allow reading readonly memory. */
1187 section
= target_section_by_addr (ops
, offset
);
1188 if (section
!= NULL
)
1190 /* Check if the section we found is readonly. */
1191 if ((bfd_get_section_flags (section
->the_bfd_section
->owner
,
1192 section
->the_bfd_section
)
1193 & SEC_READONLY
) != 0)
1195 /* Truncate the request to fit into this section. */
1196 len
= min (len
, section
->endaddr
- offset
);
1202 return TARGET_XFER_UNAVAILABLE
;
1207 /* Forward the request. */
1209 return ops
->to_xfer_partial (ops
, object
, annex
, readbuf
, writebuf
,
1210 offset
, len
, xfered_len
);
1213 /* The to_insert_breakpoint method of target record-btrace. */
1216 record_btrace_insert_breakpoint (struct target_ops
*ops
,
1217 struct gdbarch
*gdbarch
,
1218 struct bp_target_info
*bp_tgt
)
1223 /* Inserting breakpoints requires accessing memory. Allow it for the
1224 duration of this function. */
1225 old
= replay_memory_access
;
1226 replay_memory_access
= replay_memory_access_read_write
;
1231 ret
= ops
->beneath
->to_insert_breakpoint (ops
->beneath
, gdbarch
, bp_tgt
);
1233 CATCH (except
, RETURN_MASK_ALL
)
1235 replay_memory_access
= old
;
1236 throw_exception (except
);
1239 replay_memory_access
= old
;
1244 /* The to_remove_breakpoint method of target record-btrace. */
1247 record_btrace_remove_breakpoint (struct target_ops
*ops
,
1248 struct gdbarch
*gdbarch
,
1249 struct bp_target_info
*bp_tgt
)
1254 /* Removing breakpoints requires accessing memory. Allow it for the
1255 duration of this function. */
1256 old
= replay_memory_access
;
1257 replay_memory_access
= replay_memory_access_read_write
;
1262 ret
= ops
->beneath
->to_remove_breakpoint (ops
->beneath
, gdbarch
, bp_tgt
);
1264 CATCH (except
, RETURN_MASK_ALL
)
1266 replay_memory_access
= old
;
1267 throw_exception (except
);
1270 replay_memory_access
= old
;
1275 /* The to_fetch_registers method of target record-btrace. */
1278 record_btrace_fetch_registers (struct target_ops
*ops
,
1279 struct regcache
*regcache
, int regno
)
1281 struct btrace_insn_iterator
*replay
;
1282 struct thread_info
*tp
;
1284 tp
= find_thread_ptid (inferior_ptid
);
1285 gdb_assert (tp
!= NULL
);
1287 replay
= tp
->btrace
.replay
;
1288 if (replay
!= NULL
&& !record_btrace_generating_corefile
)
1290 const struct btrace_insn
*insn
;
1291 struct gdbarch
*gdbarch
;
1294 gdbarch
= get_regcache_arch (regcache
);
1295 pcreg
= gdbarch_pc_regnum (gdbarch
);
1299 /* We can only provide the PC register. */
1300 if (regno
>= 0 && regno
!= pcreg
)
1303 insn
= btrace_insn_get (replay
);
1304 gdb_assert (insn
!= NULL
);
1306 regcache_raw_supply (regcache
, regno
, &insn
->pc
);
1310 struct target_ops
*t
= ops
->beneath
;
1312 t
->to_fetch_registers (t
, regcache
, regno
);
1316 /* The to_store_registers method of target record-btrace. */
1319 record_btrace_store_registers (struct target_ops
*ops
,
1320 struct regcache
*regcache
, int regno
)
1322 struct target_ops
*t
;
1324 if (!record_btrace_generating_corefile
1325 && record_btrace_is_replaying (ops
, inferior_ptid
))
1326 error (_("Cannot write registers while replaying."));
1328 gdb_assert (may_write_registers
!= 0);
1331 t
->to_store_registers (t
, regcache
, regno
);
1334 /* The to_prepare_to_store method of target record-btrace. */
1337 record_btrace_prepare_to_store (struct target_ops
*ops
,
1338 struct regcache
*regcache
)
1340 struct target_ops
*t
;
1342 if (!record_btrace_generating_corefile
1343 && record_btrace_is_replaying (ops
, inferior_ptid
))
1347 t
->to_prepare_to_store (t
, regcache
);
1350 /* The branch trace frame cache. */
1352 struct btrace_frame_cache
1355 struct thread_info
*tp
;
1357 /* The frame info. */
1358 struct frame_info
*frame
;
1360 /* The branch trace function segment. */
1361 const struct btrace_function
*bfun
;
1364 /* A struct btrace_frame_cache hash table indexed by NEXT. */
1366 static htab_t bfcache
;
1368 /* hash_f for htab_create_alloc of bfcache. */
1371 bfcache_hash (const void *arg
)
1373 const struct btrace_frame_cache
*cache
= arg
;
1375 return htab_hash_pointer (cache
->frame
);
1378 /* eq_f for htab_create_alloc of bfcache. */
1381 bfcache_eq (const void *arg1
, const void *arg2
)
1383 const struct btrace_frame_cache
*cache1
= arg1
;
1384 const struct btrace_frame_cache
*cache2
= arg2
;
1386 return cache1
->frame
== cache2
->frame
;
1389 /* Create a new btrace frame cache. */
1391 static struct btrace_frame_cache
*
1392 bfcache_new (struct frame_info
*frame
)
1394 struct btrace_frame_cache
*cache
;
1397 cache
= FRAME_OBSTACK_ZALLOC (struct btrace_frame_cache
);
1398 cache
->frame
= frame
;
1400 slot
= htab_find_slot (bfcache
, cache
, INSERT
);
1401 gdb_assert (*slot
== NULL
);
1407 /* Extract the branch trace function from a branch trace frame. */
1409 static const struct btrace_function
*
1410 btrace_get_frame_function (struct frame_info
*frame
)
1412 const struct btrace_frame_cache
*cache
;
1413 const struct btrace_function
*bfun
;
1414 struct btrace_frame_cache pattern
;
1417 pattern
.frame
= frame
;
1419 slot
= htab_find_slot (bfcache
, &pattern
, NO_INSERT
);
1427 /* Implement stop_reason method for record_btrace_frame_unwind. */
1429 static enum unwind_stop_reason
1430 record_btrace_frame_unwind_stop_reason (struct frame_info
*this_frame
,
1433 const struct btrace_frame_cache
*cache
;
1434 const struct btrace_function
*bfun
;
1436 cache
= *this_cache
;
1438 gdb_assert (bfun
!= NULL
);
1440 if (bfun
->up
== NULL
)
1441 return UNWIND_UNAVAILABLE
;
1443 return UNWIND_NO_REASON
;
1446 /* Implement this_id method for record_btrace_frame_unwind. */
1449 record_btrace_frame_this_id (struct frame_info
*this_frame
, void **this_cache
,
1450 struct frame_id
*this_id
)
1452 const struct btrace_frame_cache
*cache
;
1453 const struct btrace_function
*bfun
;
1454 CORE_ADDR code
, special
;
1456 cache
= *this_cache
;
1459 gdb_assert (bfun
!= NULL
);
1461 while (bfun
->segment
.prev
!= NULL
)
1462 bfun
= bfun
->segment
.prev
;
1464 code
= get_frame_func (this_frame
);
1465 special
= bfun
->number
;
1467 *this_id
= frame_id_build_unavailable_stack_special (code
, special
);
1469 DEBUG ("[frame] %s id: (!stack, pc=%s, special=%s)",
1470 btrace_get_bfun_name (cache
->bfun
),
1471 core_addr_to_string_nz (this_id
->code_addr
),
1472 core_addr_to_string_nz (this_id
->special_addr
));
1475 /* Implement prev_register method for record_btrace_frame_unwind. */
1477 static struct value
*
1478 record_btrace_frame_prev_register (struct frame_info
*this_frame
,
1482 const struct btrace_frame_cache
*cache
;
1483 const struct btrace_function
*bfun
, *caller
;
1484 const struct btrace_insn
*insn
;
1485 struct gdbarch
*gdbarch
;
1489 gdbarch
= get_frame_arch (this_frame
);
1490 pcreg
= gdbarch_pc_regnum (gdbarch
);
1491 if (pcreg
< 0 || regnum
!= pcreg
)
1492 throw_error (NOT_AVAILABLE_ERROR
,
1493 _("Registers are not available in btrace record history"));
1495 cache
= *this_cache
;
1497 gdb_assert (bfun
!= NULL
);
1501 throw_error (NOT_AVAILABLE_ERROR
,
1502 _("No caller in btrace record history"));
1504 if ((bfun
->flags
& BFUN_UP_LINKS_TO_RET
) != 0)
1506 insn
= VEC_index (btrace_insn_s
, caller
->insn
, 0);
1511 insn
= VEC_last (btrace_insn_s
, caller
->insn
);
1514 pc
+= gdb_insn_length (gdbarch
, pc
);
1517 DEBUG ("[frame] unwound PC in %s on level %d: %s",
1518 btrace_get_bfun_name (bfun
), bfun
->level
,
1519 core_addr_to_string_nz (pc
));
1521 return frame_unwind_got_address (this_frame
, regnum
, pc
);
1524 /* Implement sniffer method for record_btrace_frame_unwind. */
1527 record_btrace_frame_sniffer (const struct frame_unwind
*self
,
1528 struct frame_info
*this_frame
,
1531 const struct btrace_function
*bfun
;
1532 struct btrace_frame_cache
*cache
;
1533 struct thread_info
*tp
;
1534 struct frame_info
*next
;
1536 /* THIS_FRAME does not contain a reference to its thread. */
1537 tp
= find_thread_ptid (inferior_ptid
);
1538 gdb_assert (tp
!= NULL
);
1541 next
= get_next_frame (this_frame
);
1544 const struct btrace_insn_iterator
*replay
;
1546 replay
= tp
->btrace
.replay
;
1548 bfun
= replay
->function
;
1552 const struct btrace_function
*callee
;
1554 callee
= btrace_get_frame_function (next
);
1555 if (callee
!= NULL
&& (callee
->flags
& BFUN_UP_LINKS_TO_TAILCALL
) == 0)
1562 DEBUG ("[frame] sniffed frame for %s on level %d",
1563 btrace_get_bfun_name (bfun
), bfun
->level
);
1565 /* This is our frame. Initialize the frame cache. */
1566 cache
= bfcache_new (this_frame
);
1570 *this_cache
= cache
;
1574 /* Implement sniffer method for record_btrace_tailcall_frame_unwind. */
1577 record_btrace_tailcall_frame_sniffer (const struct frame_unwind
*self
,
1578 struct frame_info
*this_frame
,
1581 const struct btrace_function
*bfun
, *callee
;
1582 struct btrace_frame_cache
*cache
;
1583 struct frame_info
*next
;
1585 next
= get_next_frame (this_frame
);
1589 callee
= btrace_get_frame_function (next
);
1593 if ((callee
->flags
& BFUN_UP_LINKS_TO_TAILCALL
) == 0)
1600 DEBUG ("[frame] sniffed tailcall frame for %s on level %d",
1601 btrace_get_bfun_name (bfun
), bfun
->level
);
1603 /* This is our frame. Initialize the frame cache. */
1604 cache
= bfcache_new (this_frame
);
1605 cache
->tp
= find_thread_ptid (inferior_ptid
);
1608 *this_cache
= cache
;
1613 record_btrace_frame_dealloc_cache (struct frame_info
*self
, void *this_cache
)
1615 struct btrace_frame_cache
*cache
;
1620 slot
= htab_find_slot (bfcache
, cache
, NO_INSERT
);
1621 gdb_assert (slot
!= NULL
);
1623 htab_remove_elt (bfcache
, cache
);
1626 /* btrace recording does not store previous memory content, neither the stack
1627 frames content. Any unwinding would return errorneous results as the stack
1628 contents no longer matches the changed PC value restored from history.
1629 Therefore this unwinder reports any possibly unwound registers as
1632 const struct frame_unwind record_btrace_frame_unwind
=
1635 record_btrace_frame_unwind_stop_reason
,
1636 record_btrace_frame_this_id
,
1637 record_btrace_frame_prev_register
,
1639 record_btrace_frame_sniffer
,
1640 record_btrace_frame_dealloc_cache
1643 const struct frame_unwind record_btrace_tailcall_frame_unwind
=
1646 record_btrace_frame_unwind_stop_reason
,
1647 record_btrace_frame_this_id
,
1648 record_btrace_frame_prev_register
,
1650 record_btrace_tailcall_frame_sniffer
,
1651 record_btrace_frame_dealloc_cache
1654 /* Implement the to_get_unwinder method. */
1656 static const struct frame_unwind
*
1657 record_btrace_to_get_unwinder (struct target_ops
*self
)
1659 return &record_btrace_frame_unwind
;
1662 /* Implement the to_get_tailcall_unwinder method. */
1664 static const struct frame_unwind
*
1665 record_btrace_to_get_tailcall_unwinder (struct target_ops
*self
)
1667 return &record_btrace_tailcall_frame_unwind
;
1670 /* Return a human-readable string for FLAG. */
1673 btrace_thread_flag_to_str (enum btrace_thread_flag flag
)
1681 return "reverse-step";
1687 return "reverse-cont";
1696 /* Indicate that TP should be resumed according to FLAG. */
1699 record_btrace_resume_thread (struct thread_info
*tp
,
1700 enum btrace_thread_flag flag
)
1702 struct btrace_thread_info
*btinfo
;
1704 DEBUG ("resuming thread %d (%s): %x (%s)", tp
->num
,
1705 target_pid_to_str (tp
->ptid
), flag
, btrace_thread_flag_to_str (flag
));
1707 btinfo
= &tp
->btrace
;
1709 /* Fetch the latest branch trace. */
1712 /* A resume request overwrites a preceding resume or stop request. */
1713 btinfo
->flags
&= ~(BTHR_MOVE
| BTHR_STOP
);
1714 btinfo
->flags
|= flag
;
1717 /* Get the current frame for TP. */
1719 static struct frame_info
*
1720 get_thread_current_frame (struct thread_info
*tp
)
1722 struct frame_info
*frame
;
1723 ptid_t old_inferior_ptid
;
1726 /* Set INFERIOR_PTID, which is implicitly used by get_current_frame. */
1727 old_inferior_ptid
= inferior_ptid
;
1728 inferior_ptid
= tp
->ptid
;
1730 /* Clear the executing flag to allow changes to the current frame.
1731 We are not actually running, yet. We just started a reverse execution
1732 command or a record goto command.
1733 For the latter, EXECUTING is false and this has no effect.
1734 For the former, EXECUTING is true and we're in to_wait, about to
1735 move the thread. Since we need to recompute the stack, we temporarily
1736 set EXECUTING to flase. */
1737 executing
= is_executing (inferior_ptid
);
1738 set_executing (inferior_ptid
, 0);
1743 frame
= get_current_frame ();
1745 CATCH (except
, RETURN_MASK_ALL
)
1747 /* Restore the previous execution state. */
1748 set_executing (inferior_ptid
, executing
);
1750 /* Restore the previous inferior_ptid. */
1751 inferior_ptid
= old_inferior_ptid
;
1753 throw_exception (except
);
1757 /* Restore the previous execution state. */
1758 set_executing (inferior_ptid
, executing
);
1760 /* Restore the previous inferior_ptid. */
1761 inferior_ptid
= old_inferior_ptid
;
1766 /* Start replaying a thread. */
1768 static struct btrace_insn_iterator
*
1769 record_btrace_start_replaying (struct thread_info
*tp
)
1771 struct btrace_insn_iterator
*replay
;
1772 struct btrace_thread_info
*btinfo
;
1774 btinfo
= &tp
->btrace
;
1777 /* We can't start replaying without trace. */
1778 if (btinfo
->begin
== NULL
)
1781 /* GDB stores the current frame_id when stepping in order to detects steps
1783 Since frames are computed differently when we're replaying, we need to
1784 recompute those stored frames and fix them up so we can still detect
1785 subroutines after we started replaying. */
1788 struct frame_info
*frame
;
1789 struct frame_id frame_id
;
1790 int upd_step_frame_id
, upd_step_stack_frame_id
;
1792 /* The current frame without replaying - computed via normal unwind. */
1793 frame
= get_thread_current_frame (tp
);
1794 frame_id
= get_frame_id (frame
);
1796 /* Check if we need to update any stepping-related frame id's. */
1797 upd_step_frame_id
= frame_id_eq (frame_id
,
1798 tp
->control
.step_frame_id
);
1799 upd_step_stack_frame_id
= frame_id_eq (frame_id
,
1800 tp
->control
.step_stack_frame_id
);
1802 /* We start replaying at the end of the branch trace. This corresponds
1803 to the current instruction. */
1804 replay
= XNEW (struct btrace_insn_iterator
);
1805 btrace_insn_end (replay
, btinfo
);
1807 /* Skip gaps at the end of the trace. */
1808 while (btrace_insn_get (replay
) == NULL
)
1812 steps
= btrace_insn_prev (replay
, 1);
1814 error (_("No trace."));
1817 /* We're not replaying, yet. */
1818 gdb_assert (btinfo
->replay
== NULL
);
1819 btinfo
->replay
= replay
;
1821 /* Make sure we're not using any stale registers. */
1822 registers_changed_ptid (tp
->ptid
);
1824 /* The current frame with replaying - computed via btrace unwind. */
1825 frame
= get_thread_current_frame (tp
);
1826 frame_id
= get_frame_id (frame
);
1828 /* Replace stepping related frames where necessary. */
1829 if (upd_step_frame_id
)
1830 tp
->control
.step_frame_id
= frame_id
;
1831 if (upd_step_stack_frame_id
)
1832 tp
->control
.step_stack_frame_id
= frame_id
;
1834 CATCH (except
, RETURN_MASK_ALL
)
1836 xfree (btinfo
->replay
);
1837 btinfo
->replay
= NULL
;
1839 registers_changed_ptid (tp
->ptid
);
1841 throw_exception (except
);
1848 /* Stop replaying a thread. */
1851 record_btrace_stop_replaying (struct thread_info
*tp
)
1853 struct btrace_thread_info
*btinfo
;
1855 btinfo
= &tp
->btrace
;
1857 xfree (btinfo
->replay
);
1858 btinfo
->replay
= NULL
;
1860 /* Make sure we're not leaving any stale registers. */
1861 registers_changed_ptid (tp
->ptid
);
1864 /* Stop replaying TP if it is at the end of its execution history. */
1867 record_btrace_stop_replaying_at_end (struct thread_info
*tp
)
1869 struct btrace_insn_iterator
*replay
, end
;
1870 struct btrace_thread_info
*btinfo
;
1872 btinfo
= &tp
->btrace
;
1873 replay
= btinfo
->replay
;
1878 btrace_insn_end (&end
, btinfo
);
1880 if (btrace_insn_cmp (replay
, &end
) == 0)
1881 record_btrace_stop_replaying (tp
);
1884 /* The to_resume method of target record-btrace. */
1887 record_btrace_resume (struct target_ops
*ops
, ptid_t ptid
, int step
,
1888 enum gdb_signal signal
)
1890 struct thread_info
*tp
;
1891 enum btrace_thread_flag flag
;
1894 DEBUG ("resume %s: %s%s", target_pid_to_str (ptid
),
1895 execution_direction
== EXEC_REVERSE
? "reverse-" : "",
1896 step
? "step" : "cont");
1900 /* Store the execution direction of the last resume.
1902 If there is more than one to_resume call, we have to rely on infrun
1903 to not change the execution direction in-between. */
1904 record_btrace_resume_exec_dir
= execution_direction
;
1906 /* For all-stop targets we pick the current thread when asked to resume an
1907 entire process or everything. */
1908 if (!target_is_non_stop_p ())
1910 if (ptid_equal (minus_one_ptid
, ptid
) || ptid_is_pid (ptid
))
1911 ptid
= inferior_ptid
;
1913 tp
= find_thread_ptid (ptid
);
1915 error (_("Cannot find thread to resume."));
1918 /* As long as we're not replaying, just forward the request.
1920 For non-stop targets this means that no thread is replaying. In order to
1921 make progress, we may need to explicitly move replaying threads to the end
1922 of their execution history. */
1923 if ((execution_direction
!= EXEC_REVERSE
)
1924 && !record_btrace_is_replaying (ops
, minus_one_ptid
))
1927 return ops
->to_resume (ops
, orig_ptid
, step
, signal
);
1930 /* Compute the btrace thread flag for the requested move. */
1932 flag
= execution_direction
== EXEC_REVERSE
? BTHR_RCONT
: BTHR_CONT
;
1934 flag
= execution_direction
== EXEC_REVERSE
? BTHR_RSTEP
: BTHR_STEP
;
1936 /* We just indicate the resume intent here. The actual stepping happens in
1937 record_btrace_wait below. */
1938 ALL_NON_EXITED_THREADS (tp
)
1939 if (ptid_match (tp
->ptid
, ptid
))
1940 record_btrace_resume_thread (tp
, flag
);
1942 /* Async support. */
1943 if (target_can_async_p ())
1946 mark_async_event_handler (record_btrace_async_inferior_event_handler
);
1950 /* Cancel resuming TP. */
1953 record_btrace_cancel_resume (struct thread_info
*tp
)
1955 enum btrace_thread_flag flags
;
1957 flags
= tp
->btrace
.flags
& (BTHR_MOVE
| BTHR_STOP
);
1961 DEBUG ("cancel resume thread %d (%s): %x (%s)", tp
->num
,
1962 target_pid_to_str (tp
->ptid
), flags
,
1963 btrace_thread_flag_to_str (flags
));
1965 tp
->btrace
.flags
&= ~(BTHR_MOVE
| BTHR_STOP
);
1966 record_btrace_stop_replaying_at_end (tp
);
1969 /* Return a target_waitstatus indicating that we ran out of history. */
1971 static struct target_waitstatus
1972 btrace_step_no_history (void)
1974 struct target_waitstatus status
;
1976 status
.kind
= TARGET_WAITKIND_NO_HISTORY
;
1981 /* Return a target_waitstatus indicating that a step finished. */
1983 static struct target_waitstatus
1984 btrace_step_stopped (void)
1986 struct target_waitstatus status
;
1988 status
.kind
= TARGET_WAITKIND_STOPPED
;
1989 status
.value
.sig
= GDB_SIGNAL_TRAP
;
1994 /* Return a target_waitstatus indicating that a thread was stopped as
1997 static struct target_waitstatus
1998 btrace_step_stopped_on_request (void)
2000 struct target_waitstatus status
;
2002 status
.kind
= TARGET_WAITKIND_STOPPED
;
2003 status
.value
.sig
= GDB_SIGNAL_0
;
2008 /* Return a target_waitstatus indicating a spurious stop. */
2010 static struct target_waitstatus
2011 btrace_step_spurious (void)
2013 struct target_waitstatus status
;
2015 status
.kind
= TARGET_WAITKIND_SPURIOUS
;
2020 /* Return a target_waitstatus indicating that the thread was not resumed. */
2022 static struct target_waitstatus
2023 btrace_step_no_resumed (void)
2025 struct target_waitstatus status
;
2027 status
.kind
= TARGET_WAITKIND_NO_RESUMED
;
2032 /* Return a target_waitstatus indicating that we should wait again. */
2034 static struct target_waitstatus
2035 btrace_step_again (void)
2037 struct target_waitstatus status
;
2039 status
.kind
= TARGET_WAITKIND_IGNORE
;
2044 /* Clear the record histories. */
2047 record_btrace_clear_histories (struct btrace_thread_info
*btinfo
)
2049 xfree (btinfo
->insn_history
);
2050 xfree (btinfo
->call_history
);
2052 btinfo
->insn_history
= NULL
;
2053 btinfo
->call_history
= NULL
;
2056 /* Check whether TP's current replay position is at a breakpoint. */
2059 record_btrace_replay_at_breakpoint (struct thread_info
*tp
)
2061 struct btrace_insn_iterator
*replay
;
2062 struct btrace_thread_info
*btinfo
;
2063 const struct btrace_insn
*insn
;
2064 struct inferior
*inf
;
2066 btinfo
= &tp
->btrace
;
2067 replay
= btinfo
->replay
;
2072 insn
= btrace_insn_get (replay
);
2076 inf
= find_inferior_ptid (tp
->ptid
);
2080 return record_check_stopped_by_breakpoint (inf
->aspace
, insn
->pc
,
2081 &btinfo
->stop_reason
);
2084 /* Step one instruction in forward direction. */
2086 static struct target_waitstatus
2087 record_btrace_single_step_forward (struct thread_info
*tp
)
2089 struct btrace_insn_iterator
*replay
, end
;
2090 struct btrace_thread_info
*btinfo
;
2092 btinfo
= &tp
->btrace
;
2093 replay
= btinfo
->replay
;
2095 /* We're done if we're not replaying. */
2097 return btrace_step_no_history ();
2099 /* Check if we're stepping a breakpoint. */
2100 if (record_btrace_replay_at_breakpoint (tp
))
2101 return btrace_step_stopped ();
2103 /* Skip gaps during replay. */
2108 /* We will bail out here if we continue stepping after reaching the end
2109 of the execution history. */
2110 steps
= btrace_insn_next (replay
, 1);
2112 return btrace_step_no_history ();
2114 while (btrace_insn_get (replay
) == NULL
);
2116 /* Determine the end of the instruction trace. */
2117 btrace_insn_end (&end
, btinfo
);
2119 /* The execution trace contains (and ends with) the current instruction.
2120 This instruction has not been executed, yet, so the trace really ends
2121 one instruction earlier. */
2122 if (btrace_insn_cmp (replay
, &end
) == 0)
2123 return btrace_step_no_history ();
2125 return btrace_step_spurious ();
2128 /* Step one instruction in backward direction. */
2130 static struct target_waitstatus
2131 record_btrace_single_step_backward (struct thread_info
*tp
)
2133 struct btrace_insn_iterator
*replay
;
2134 struct btrace_thread_info
*btinfo
;
2136 btinfo
= &tp
->btrace
;
2137 replay
= btinfo
->replay
;
2139 /* Start replaying if we're not already doing so. */
2141 replay
= record_btrace_start_replaying (tp
);
2143 /* If we can't step any further, we reached the end of the history.
2144 Skip gaps during replay. */
2149 steps
= btrace_insn_prev (replay
, 1);
2151 return btrace_step_no_history ();
2153 while (btrace_insn_get (replay
) == NULL
);
2155 /* Check if we're stepping a breakpoint.
2157 For reverse-stepping, this check is after the step. There is logic in
2158 infrun.c that handles reverse-stepping separately. See, for example,
2159 proceed and adjust_pc_after_break.
2161 This code assumes that for reverse-stepping, PC points to the last
2162 de-executed instruction, whereas for forward-stepping PC points to the
2163 next to-be-executed instruction. */
2164 if (record_btrace_replay_at_breakpoint (tp
))
2165 return btrace_step_stopped ();
2167 return btrace_step_spurious ();
2170 /* Step a single thread. */
2172 static struct target_waitstatus
2173 record_btrace_step_thread (struct thread_info
*tp
)
2175 struct btrace_thread_info
*btinfo
;
2176 struct target_waitstatus status
;
2177 enum btrace_thread_flag flags
;
2179 btinfo
= &tp
->btrace
;
2181 flags
= btinfo
->flags
& (BTHR_MOVE
| BTHR_STOP
);
2182 btinfo
->flags
&= ~(BTHR_MOVE
| BTHR_STOP
);
2184 DEBUG ("stepping thread %d (%s): %x (%s)", tp
->num
,
2185 target_pid_to_str (tp
->ptid
), flags
,
2186 btrace_thread_flag_to_str (flags
));
2188 /* We can't step without an execution history. */
2189 if ((flags
& BTHR_MOVE
) != 0 && btrace_is_empty (tp
))
2190 return btrace_step_no_history ();
2195 internal_error (__FILE__
, __LINE__
, _("invalid stepping type."));
2198 return btrace_step_stopped_on_request ();
2201 status
= record_btrace_single_step_forward (tp
);
2202 if (status
.kind
!= TARGET_WAITKIND_SPURIOUS
)
2205 return btrace_step_stopped ();
2208 status
= record_btrace_single_step_backward (tp
);
2209 if (status
.kind
!= TARGET_WAITKIND_SPURIOUS
)
2212 return btrace_step_stopped ();
2215 status
= record_btrace_single_step_forward (tp
);
2216 if (status
.kind
!= TARGET_WAITKIND_SPURIOUS
)
2219 btinfo
->flags
|= flags
;
2220 return btrace_step_again ();
2223 status
= record_btrace_single_step_backward (tp
);
2224 if (status
.kind
!= TARGET_WAITKIND_SPURIOUS
)
2227 btinfo
->flags
|= flags
;
2228 return btrace_step_again ();
2231 /* We keep threads moving at the end of their execution history. The to_wait
2232 method will stop the thread for whom the event is reported. */
2233 if (status
.kind
== TARGET_WAITKIND_NO_HISTORY
)
2234 btinfo
->flags
|= flags
;
2239 /* A vector of threads. */
2241 typedef struct thread_info
* tp_t
;
2244 /* Announce further events if necessary. */
2247 record_btrace_maybe_mark_async_event (const VEC (tp_t
) *moving
,
2248 const VEC (tp_t
) *no_history
)
2250 int more_moving
, more_no_history
;
2252 more_moving
= !VEC_empty (tp_t
, moving
);
2253 more_no_history
= !VEC_empty (tp_t
, no_history
);
2255 if (!more_moving
&& !more_no_history
)
2259 DEBUG ("movers pending");
2261 if (more_no_history
)
2262 DEBUG ("no-history pending");
2264 mark_async_event_handler (record_btrace_async_inferior_event_handler
);
2267 /* The to_wait method of target record-btrace. */
2270 record_btrace_wait (struct target_ops
*ops
, ptid_t ptid
,
2271 struct target_waitstatus
*status
, int options
)
2273 VEC (tp_t
) *moving
, *no_history
;
2274 struct thread_info
*tp
, *eventing
;
2275 struct cleanup
*cleanups
= make_cleanup (null_cleanup
, NULL
);
2277 DEBUG ("wait %s (0x%x)", target_pid_to_str (ptid
), options
);
2279 /* As long as we're not replaying, just forward the request. */
2280 if ((execution_direction
!= EXEC_REVERSE
)
2281 && !record_btrace_is_replaying (ops
, minus_one_ptid
))
2284 return ops
->to_wait (ops
, ptid
, status
, options
);
2290 make_cleanup (VEC_cleanup (tp_t
), &moving
);
2291 make_cleanup (VEC_cleanup (tp_t
), &no_history
);
2293 /* Keep a work list of moving threads. */
2294 ALL_NON_EXITED_THREADS (tp
)
2295 if (ptid_match (tp
->ptid
, ptid
)
2296 && ((tp
->btrace
.flags
& (BTHR_MOVE
| BTHR_STOP
)) != 0))
2297 VEC_safe_push (tp_t
, moving
, tp
);
2299 if (VEC_empty (tp_t
, moving
))
2301 *status
= btrace_step_no_resumed ();
2303 DEBUG ("wait ended by %s: %s", target_pid_to_str (null_ptid
),
2304 target_waitstatus_to_string (status
));
2306 do_cleanups (cleanups
);
2310 /* Step moving threads one by one, one step each, until either one thread
2311 reports an event or we run out of threads to step.
2313 When stepping more than one thread, chances are that some threads reach
2314 the end of their execution history earlier than others. If we reported
2315 this immediately, all-stop on top of non-stop would stop all threads and
2316 resume the same threads next time. And we would report the same thread
2317 having reached the end of its execution history again.
2319 In the worst case, this would starve the other threads. But even if other
2320 threads would be allowed to make progress, this would result in far too
2321 many intermediate stops.
2323 We therefore delay the reporting of "no execution history" until we have
2324 nothing else to report. By this time, all threads should have moved to
2325 either the beginning or the end of their execution history. There will
2326 be a single user-visible stop. */
2328 while ((eventing
== NULL
) && !VEC_empty (tp_t
, moving
))
2333 while ((eventing
== NULL
) && VEC_iterate (tp_t
, moving
, ix
, tp
))
2335 *status
= record_btrace_step_thread (tp
);
2337 switch (status
->kind
)
2339 case TARGET_WAITKIND_IGNORE
:
2343 case TARGET_WAITKIND_NO_HISTORY
:
2344 VEC_safe_push (tp_t
, no_history
,
2345 VEC_ordered_remove (tp_t
, moving
, ix
));
2349 eventing
= VEC_unordered_remove (tp_t
, moving
, ix
);
2355 if (eventing
== NULL
)
2357 /* We started with at least one moving thread. This thread must have
2358 either stopped or reached the end of its execution history.
2360 In the former case, EVENTING must not be NULL.
2361 In the latter case, NO_HISTORY must not be empty. */
2362 gdb_assert (!VEC_empty (tp_t
, no_history
));
2364 /* We kept threads moving at the end of their execution history. Stop
2365 EVENTING now that we are going to report its stop. */
2366 eventing
= VEC_unordered_remove (tp_t
, no_history
, 0);
2367 eventing
->btrace
.flags
&= ~BTHR_MOVE
;
2369 *status
= btrace_step_no_history ();
2372 gdb_assert (eventing
!= NULL
);
2374 /* We kept threads replaying at the end of their execution history. Stop
2375 replaying EVENTING now that we are going to report its stop. */
2376 record_btrace_stop_replaying_at_end (eventing
);
2378 /* Stop all other threads. */
2379 if (!target_is_non_stop_p ())
2380 ALL_NON_EXITED_THREADS (tp
)
2381 record_btrace_cancel_resume (tp
);
2383 /* In async mode, we need to announce further events. */
2384 if (target_is_async_p ())
2385 record_btrace_maybe_mark_async_event (moving
, no_history
);
2387 /* Start record histories anew from the current position. */
2388 record_btrace_clear_histories (&eventing
->btrace
);
2390 /* We moved the replay position but did not update registers. */
2391 registers_changed_ptid (eventing
->ptid
);
2393 DEBUG ("wait ended by thread %d (%s): %s", eventing
->num
,
2394 target_pid_to_str (eventing
->ptid
),
2395 target_waitstatus_to_string (status
));
2397 do_cleanups (cleanups
);
2398 return eventing
->ptid
;
2401 /* The to_stop method of target record-btrace. */
2404 record_btrace_stop (struct target_ops
*ops
, ptid_t ptid
)
2406 DEBUG ("stop %s", target_pid_to_str (ptid
));
2408 /* As long as we're not replaying, just forward the request. */
2409 if ((execution_direction
!= EXEC_REVERSE
)
2410 && !record_btrace_is_replaying (ops
, minus_one_ptid
))
2413 ops
->to_stop (ops
, ptid
);
2417 struct thread_info
*tp
;
2419 ALL_NON_EXITED_THREADS (tp
)
2420 if (ptid_match (tp
->ptid
, ptid
))
2422 tp
->btrace
.flags
&= ~BTHR_MOVE
;
2423 tp
->btrace
.flags
|= BTHR_STOP
;
2428 /* The to_can_execute_reverse method of target record-btrace. */
2431 record_btrace_can_execute_reverse (struct target_ops
*self
)
2436 /* The to_stopped_by_sw_breakpoint method of target record-btrace. */
2439 record_btrace_stopped_by_sw_breakpoint (struct target_ops
*ops
)
2441 if (record_btrace_is_replaying (ops
, minus_one_ptid
))
2443 struct thread_info
*tp
= inferior_thread ();
2445 return tp
->btrace
.stop_reason
== TARGET_STOPPED_BY_SW_BREAKPOINT
;
2448 return ops
->beneath
->to_stopped_by_sw_breakpoint (ops
->beneath
);
2451 /* The to_supports_stopped_by_sw_breakpoint method of target
2455 record_btrace_supports_stopped_by_sw_breakpoint (struct target_ops
*ops
)
2457 if (record_btrace_is_replaying (ops
, minus_one_ptid
))
2460 return ops
->beneath
->to_supports_stopped_by_sw_breakpoint (ops
->beneath
);
2463 /* The to_stopped_by_sw_breakpoint method of target record-btrace. */
2466 record_btrace_stopped_by_hw_breakpoint (struct target_ops
*ops
)
2468 if (record_btrace_is_replaying (ops
, minus_one_ptid
))
2470 struct thread_info
*tp
= inferior_thread ();
2472 return tp
->btrace
.stop_reason
== TARGET_STOPPED_BY_HW_BREAKPOINT
;
2475 return ops
->beneath
->to_stopped_by_hw_breakpoint (ops
->beneath
);
2478 /* The to_supports_stopped_by_hw_breakpoint method of target
2482 record_btrace_supports_stopped_by_hw_breakpoint (struct target_ops
*ops
)
2484 if (record_btrace_is_replaying (ops
, minus_one_ptid
))
2487 return ops
->beneath
->to_supports_stopped_by_hw_breakpoint (ops
->beneath
);
2490 /* The to_update_thread_list method of target record-btrace. */
2493 record_btrace_update_thread_list (struct target_ops
*ops
)
2495 /* We don't add or remove threads during replay. */
2496 if (record_btrace_is_replaying (ops
, minus_one_ptid
))
2499 /* Forward the request. */
2501 ops
->to_update_thread_list (ops
);
2504 /* The to_thread_alive method of target record-btrace. */
2507 record_btrace_thread_alive (struct target_ops
*ops
, ptid_t ptid
)
2509 /* We don't add or remove threads during replay. */
2510 if (record_btrace_is_replaying (ops
, minus_one_ptid
))
2511 return find_thread_ptid (ptid
) != NULL
;
2513 /* Forward the request. */
2515 return ops
->to_thread_alive (ops
, ptid
);
2518 /* Set the replay branch trace instruction iterator. If IT is NULL, replay
2522 record_btrace_set_replay (struct thread_info
*tp
,
2523 const struct btrace_insn_iterator
*it
)
2525 struct btrace_thread_info
*btinfo
;
2527 btinfo
= &tp
->btrace
;
2529 if (it
== NULL
|| it
->function
== NULL
)
2530 record_btrace_stop_replaying (tp
);
2533 if (btinfo
->replay
== NULL
)
2534 record_btrace_start_replaying (tp
);
2535 else if (btrace_insn_cmp (btinfo
->replay
, it
) == 0)
2538 *btinfo
->replay
= *it
;
2539 registers_changed_ptid (tp
->ptid
);
2542 /* Start anew from the new replay position. */
2543 record_btrace_clear_histories (btinfo
);
2545 stop_pc
= regcache_read_pc (get_current_regcache ());
2546 print_stack_frame (get_selected_frame (NULL
), 1, SRC_AND_LOC
, 1);
2549 /* The to_goto_record_begin method of target record-btrace. */
2552 record_btrace_goto_begin (struct target_ops
*self
)
2554 struct thread_info
*tp
;
2555 struct btrace_insn_iterator begin
;
2557 tp
= require_btrace_thread ();
2559 btrace_insn_begin (&begin
, &tp
->btrace
);
2560 record_btrace_set_replay (tp
, &begin
);
2563 /* The to_goto_record_end method of target record-btrace. */
2566 record_btrace_goto_end (struct target_ops
*ops
)
2568 struct thread_info
*tp
;
2570 tp
= require_btrace_thread ();
2572 record_btrace_set_replay (tp
, NULL
);
2575 /* The to_goto_record method of target record-btrace. */
2578 record_btrace_goto (struct target_ops
*self
, ULONGEST insn
)
2580 struct thread_info
*tp
;
2581 struct btrace_insn_iterator it
;
2582 unsigned int number
;
2587 /* Check for wrap-arounds. */
2589 error (_("Instruction number out of range."));
2591 tp
= require_btrace_thread ();
2593 found
= btrace_find_insn_by_number (&it
, &tp
->btrace
, number
);
2595 error (_("No such instruction."));
2597 record_btrace_set_replay (tp
, &it
);
2600 /* The to_record_stop_replaying method of target record-btrace. */
2603 record_btrace_stop_replaying_all (struct target_ops
*self
)
2605 struct thread_info
*tp
;
2607 ALL_NON_EXITED_THREADS (tp
)
2608 record_btrace_stop_replaying (tp
);
2611 /* The to_execution_direction target method. */
2613 static enum exec_direction_kind
2614 record_btrace_execution_direction (struct target_ops
*self
)
2616 return record_btrace_resume_exec_dir
;
2619 /* The to_prepare_to_generate_core target method. */
2622 record_btrace_prepare_to_generate_core (struct target_ops
*self
)
2624 record_btrace_generating_corefile
= 1;
2627 /* The to_done_generating_core target method. */
2630 record_btrace_done_generating_core (struct target_ops
*self
)
2632 record_btrace_generating_corefile
= 0;
2635 /* Initialize the record-btrace target ops. */
2638 init_record_btrace_ops (void)
2640 struct target_ops
*ops
;
2642 ops
= &record_btrace_ops
;
2643 ops
->to_shortname
= "record-btrace";
2644 ops
->to_longname
= "Branch tracing target";
2645 ops
->to_doc
= "Collect control-flow trace and provide the execution history.";
2646 ops
->to_open
= record_btrace_open
;
2647 ops
->to_close
= record_btrace_close
;
2648 ops
->to_async
= record_btrace_async
;
2649 ops
->to_detach
= record_detach
;
2650 ops
->to_disconnect
= record_disconnect
;
2651 ops
->to_mourn_inferior
= record_mourn_inferior
;
2652 ops
->to_kill
= record_kill
;
2653 ops
->to_stop_recording
= record_btrace_stop_recording
;
2654 ops
->to_info_record
= record_btrace_info
;
2655 ops
->to_insn_history
= record_btrace_insn_history
;
2656 ops
->to_insn_history_from
= record_btrace_insn_history_from
;
2657 ops
->to_insn_history_range
= record_btrace_insn_history_range
;
2658 ops
->to_call_history
= record_btrace_call_history
;
2659 ops
->to_call_history_from
= record_btrace_call_history_from
;
2660 ops
->to_call_history_range
= record_btrace_call_history_range
;
2661 ops
->to_record_is_replaying
= record_btrace_is_replaying
;
2662 ops
->to_record_will_replay
= record_btrace_will_replay
;
2663 ops
->to_record_stop_replaying
= record_btrace_stop_replaying_all
;
2664 ops
->to_xfer_partial
= record_btrace_xfer_partial
;
2665 ops
->to_remove_breakpoint
= record_btrace_remove_breakpoint
;
2666 ops
->to_insert_breakpoint
= record_btrace_insert_breakpoint
;
2667 ops
->to_fetch_registers
= record_btrace_fetch_registers
;
2668 ops
->to_store_registers
= record_btrace_store_registers
;
2669 ops
->to_prepare_to_store
= record_btrace_prepare_to_store
;
2670 ops
->to_get_unwinder
= &record_btrace_to_get_unwinder
;
2671 ops
->to_get_tailcall_unwinder
= &record_btrace_to_get_tailcall_unwinder
;
2672 ops
->to_resume
= record_btrace_resume
;
2673 ops
->to_wait
= record_btrace_wait
;
2674 ops
->to_stop
= record_btrace_stop
;
2675 ops
->to_update_thread_list
= record_btrace_update_thread_list
;
2676 ops
->to_thread_alive
= record_btrace_thread_alive
;
2677 ops
->to_goto_record_begin
= record_btrace_goto_begin
;
2678 ops
->to_goto_record_end
= record_btrace_goto_end
;
2679 ops
->to_goto_record
= record_btrace_goto
;
2680 ops
->to_can_execute_reverse
= record_btrace_can_execute_reverse
;
2681 ops
->to_stopped_by_sw_breakpoint
= record_btrace_stopped_by_sw_breakpoint
;
2682 ops
->to_supports_stopped_by_sw_breakpoint
2683 = record_btrace_supports_stopped_by_sw_breakpoint
;
2684 ops
->to_stopped_by_hw_breakpoint
= record_btrace_stopped_by_hw_breakpoint
;
2685 ops
->to_supports_stopped_by_hw_breakpoint
2686 = record_btrace_supports_stopped_by_hw_breakpoint
;
2687 ops
->to_execution_direction
= record_btrace_execution_direction
;
2688 ops
->to_prepare_to_generate_core
= record_btrace_prepare_to_generate_core
;
2689 ops
->to_done_generating_core
= record_btrace_done_generating_core
;
2690 ops
->to_stratum
= record_stratum
;
2691 ops
->to_magic
= OPS_MAGIC
;
2694 /* Start recording in BTS format. */
2697 cmd_record_btrace_bts_start (char *args
, int from_tty
)
2699 if (args
!= NULL
&& *args
!= 0)
2700 error (_("Invalid argument."));
2702 record_btrace_conf
.format
= BTRACE_FORMAT_BTS
;
2706 execute_command ("target record-btrace", from_tty
);
2708 CATCH (exception
, RETURN_MASK_ALL
)
2710 record_btrace_conf
.format
= BTRACE_FORMAT_NONE
;
2711 throw_exception (exception
);
2716 /* Start recording Intel(R) Processor Trace. */
2719 cmd_record_btrace_pt_start (char *args
, int from_tty
)
2721 if (args
!= NULL
&& *args
!= 0)
2722 error (_("Invalid argument."));
2724 record_btrace_conf
.format
= BTRACE_FORMAT_PT
;
2728 execute_command ("target record-btrace", from_tty
);
2730 CATCH (exception
, RETURN_MASK_ALL
)
2732 record_btrace_conf
.format
= BTRACE_FORMAT_NONE
;
2733 throw_exception (exception
);
2738 /* Alias for "target record". */
2741 cmd_record_btrace_start (char *args
, int from_tty
)
2743 if (args
!= NULL
&& *args
!= 0)
2744 error (_("Invalid argument."));
2746 record_btrace_conf
.format
= BTRACE_FORMAT_PT
;
2750 execute_command ("target record-btrace", from_tty
);
2752 CATCH (exception
, RETURN_MASK_ALL
)
2754 record_btrace_conf
.format
= BTRACE_FORMAT_BTS
;
2758 execute_command ("target record-btrace", from_tty
);
2760 CATCH (exception
, RETURN_MASK_ALL
)
2762 record_btrace_conf
.format
= BTRACE_FORMAT_NONE
;
2763 throw_exception (exception
);
2770 /* The "set record btrace" command. */
2773 cmd_set_record_btrace (char *args
, int from_tty
)
2775 cmd_show_list (set_record_btrace_cmdlist
, from_tty
, "");
2778 /* The "show record btrace" command. */
2781 cmd_show_record_btrace (char *args
, int from_tty
)
2783 cmd_show_list (show_record_btrace_cmdlist
, from_tty
, "");
2786 /* The "show record btrace replay-memory-access" command. */
2789 cmd_show_replay_memory_access (struct ui_file
*file
, int from_tty
,
2790 struct cmd_list_element
*c
, const char *value
)
2792 fprintf_filtered (gdb_stdout
, _("Replay memory access is %s.\n"),
2793 replay_memory_access
);
2796 /* The "set record btrace bts" command. */
2799 cmd_set_record_btrace_bts (char *args
, int from_tty
)
2801 printf_unfiltered (_("\"set record btrace bts\" must be followed "
2802 "by an appropriate subcommand.\n"));
2803 help_list (set_record_btrace_bts_cmdlist
, "set record btrace bts ",
2804 all_commands
, gdb_stdout
);
2807 /* The "show record btrace bts" command. */
2810 cmd_show_record_btrace_bts (char *args
, int from_tty
)
2812 cmd_show_list (show_record_btrace_bts_cmdlist
, from_tty
, "");
2815 /* The "set record btrace pt" command. */
2818 cmd_set_record_btrace_pt (char *args
, int from_tty
)
2820 printf_unfiltered (_("\"set record btrace pt\" must be followed "
2821 "by an appropriate subcommand.\n"));
2822 help_list (set_record_btrace_pt_cmdlist
, "set record btrace pt ",
2823 all_commands
, gdb_stdout
);
2826 /* The "show record btrace pt" command. */
2829 cmd_show_record_btrace_pt (char *args
, int from_tty
)
2831 cmd_show_list (show_record_btrace_pt_cmdlist
, from_tty
, "");
2834 /* The "record bts buffer-size" show value function. */
2837 show_record_bts_buffer_size_value (struct ui_file
*file
, int from_tty
,
2838 struct cmd_list_element
*c
,
2841 fprintf_filtered (file
, _("The record/replay bts buffer size is %s.\n"),
2845 /* The "record pt buffer-size" show value function. */
2848 show_record_pt_buffer_size_value (struct ui_file
*file
, int from_tty
,
2849 struct cmd_list_element
*c
,
2852 fprintf_filtered (file
, _("The record/replay pt buffer size is %s.\n"),
2856 void _initialize_record_btrace (void);
2858 /* Initialize btrace commands. */
2861 _initialize_record_btrace (void)
2863 add_prefix_cmd ("btrace", class_obscure
, cmd_record_btrace_start
,
2864 _("Start branch trace recording."), &record_btrace_cmdlist
,
2865 "record btrace ", 0, &record_cmdlist
);
2866 add_alias_cmd ("b", "btrace", class_obscure
, 1, &record_cmdlist
);
2868 add_cmd ("bts", class_obscure
, cmd_record_btrace_bts_start
,
2870 Start branch trace recording in Branch Trace Store (BTS) format.\n\n\
2871 The processor stores a from/to record for each branch into a cyclic buffer.\n\
2872 This format may not be available on all processors."),
2873 &record_btrace_cmdlist
);
2874 add_alias_cmd ("bts", "btrace bts", class_obscure
, 1, &record_cmdlist
);
2876 add_cmd ("pt", class_obscure
, cmd_record_btrace_pt_start
,
2878 Start branch trace recording in Intel(R) Processor Trace format.\n\n\
2879 This format may not be available on all processors."),
2880 &record_btrace_cmdlist
);
2881 add_alias_cmd ("pt", "btrace pt", class_obscure
, 1, &record_cmdlist
);
2883 add_prefix_cmd ("btrace", class_support
, cmd_set_record_btrace
,
2884 _("Set record options"), &set_record_btrace_cmdlist
,
2885 "set record btrace ", 0, &set_record_cmdlist
);
2887 add_prefix_cmd ("btrace", class_support
, cmd_show_record_btrace
,
2888 _("Show record options"), &show_record_btrace_cmdlist
,
2889 "show record btrace ", 0, &show_record_cmdlist
);
2891 add_setshow_enum_cmd ("replay-memory-access", no_class
,
2892 replay_memory_access_types
, &replay_memory_access
, _("\
2893 Set what memory accesses are allowed during replay."), _("\
2894 Show what memory accesses are allowed during replay."),
2895 _("Default is READ-ONLY.\n\n\
2896 The btrace record target does not trace data.\n\
2897 The memory therefore corresponds to the live target and not \
2898 to the current replay position.\n\n\
2899 When READ-ONLY, allow accesses to read-only memory during replay.\n\
2900 When READ-WRITE, allow accesses to read-only and read-write memory during \
2902 NULL
, cmd_show_replay_memory_access
,
2903 &set_record_btrace_cmdlist
,
2904 &show_record_btrace_cmdlist
);
2906 add_prefix_cmd ("bts", class_support
, cmd_set_record_btrace_bts
,
2907 _("Set record btrace bts options"),
2908 &set_record_btrace_bts_cmdlist
,
2909 "set record btrace bts ", 0, &set_record_btrace_cmdlist
);
2911 add_prefix_cmd ("bts", class_support
, cmd_show_record_btrace_bts
,
2912 _("Show record btrace bts options"),
2913 &show_record_btrace_bts_cmdlist
,
2914 "show record btrace bts ", 0, &show_record_btrace_cmdlist
);
2916 add_setshow_uinteger_cmd ("buffer-size", no_class
,
2917 &record_btrace_conf
.bts
.size
,
2918 _("Set the record/replay bts buffer size."),
2919 _("Show the record/replay bts buffer size."), _("\
2920 When starting recording request a trace buffer of this size. \
2921 The actual buffer size may differ from the requested size. \
2922 Use \"info record\" to see the actual buffer size.\n\n\
2923 Bigger buffers allow longer recording but also take more time to process \
2924 the recorded execution trace.\n\n\
2925 The trace buffer size may not be changed while recording."), NULL
,
2926 show_record_bts_buffer_size_value
,
2927 &set_record_btrace_bts_cmdlist
,
2928 &show_record_btrace_bts_cmdlist
);
2930 add_prefix_cmd ("pt", class_support
, cmd_set_record_btrace_pt
,
2931 _("Set record btrace pt options"),
2932 &set_record_btrace_pt_cmdlist
,
2933 "set record btrace pt ", 0, &set_record_btrace_cmdlist
);
2935 add_prefix_cmd ("pt", class_support
, cmd_show_record_btrace_pt
,
2936 _("Show record btrace pt options"),
2937 &show_record_btrace_pt_cmdlist
,
2938 "show record btrace pt ", 0, &show_record_btrace_cmdlist
);
2940 add_setshow_uinteger_cmd ("buffer-size", no_class
,
2941 &record_btrace_conf
.pt
.size
,
2942 _("Set the record/replay pt buffer size."),
2943 _("Show the record/replay pt buffer size."), _("\
2944 Bigger buffers allow longer recording but also take more time to process \
2945 the recorded execution.\n\
2946 The actual buffer size may differ from the requested size. Use \"info record\" \
2947 to see the actual buffer size."), NULL
, show_record_pt_buffer_size_value
,
2948 &set_record_btrace_pt_cmdlist
,
2949 &show_record_btrace_pt_cmdlist
);
2951 init_record_btrace_ops ();
2952 add_target (&record_btrace_ops
);
2954 bfcache
= htab_create_alloc (50, bfcache_hash
, bfcache_eq
, NULL
,
2957 record_btrace_conf
.bts
.size
= 64 * 1024;
2958 record_btrace_conf
.pt
.size
= 16 * 1024;