static void record_btrace_call_history_range (struct target_ops *self, ULONGEST from, ULONGEST to, int flags) { struct btrace_thread_info *btinfo; struct btrace_call_history *history; struct btrace_call_iterator begin, end; struct cleanup *uiout_cleanup; struct ui_out *uiout; unsigned int low, high; int found; uiout = current_uiout; uiout_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, "func history"); low = from; high = to; DEBUG ("call-history (0x%x): [%u; %u)", flags, low, high); /* Check for wrap-arounds. */ if (low != from || high != to) error (_("Bad range.")); if (high < low) error (_("Bad range.")); btinfo = require_btrace (); found = btrace_find_call_by_number (&begin, btinfo, low); if (found == 0) error (_("Range out of bounds.")); found = btrace_find_call_by_number (&end, btinfo, high); if (found == 0) { /* Silently truncate the range. */ btrace_call_end (&end, btinfo); } else { /* We want both begin and end to be inclusive. */ btrace_call_next (&end, 1); } btrace_call_history (uiout, btinfo, &begin, &end, flags); btrace_set_call_history (btinfo, &begin, &end); do_cleanups (uiout_cleanup); }
static void record_btrace_call_history_range (ULONGEST from, ULONGEST to, int flags) { struct btrace_thread_info *btinfo; struct cleanup *uiout_cleanup; struct ui_out *uiout; unsigned int last, begin, end; uiout = current_uiout; uiout_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, "func history"); btinfo = require_btrace (); last = VEC_length (btrace_func_s, btinfo->ftrace); begin = (unsigned int) from; end = (unsigned int) to; DEBUG ("func-history (0x%x): [%u; %u[", flags, begin, end); /* Check for wrap-arounds. */ if (begin != from || end != to) error (_("Bad range.")); if (end <= begin) error (_("Bad range.")); if (last <= begin) error (_("Range out of bounds.")); /* Truncate the range, if necessary. */ if (last < end) end = last; btrace_func_history (btinfo, uiout, begin, end, flags); btinfo->func_iterator.begin = begin; btinfo->func_iterator.end = end; do_cleanups (uiout_cleanup); }
static void record_btrace_call_history (int size, int flags) { struct btrace_thread_info *btinfo; struct cleanup *uiout_cleanup; struct ui_out *uiout; unsigned int context, last, begin, end; uiout = current_uiout; uiout_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, "insn history"); btinfo = require_btrace (); last = VEC_length (btrace_func_s, btinfo->ftrace); context = abs (size); begin = btinfo->func_iterator.begin; end = btinfo->func_iterator.end; DEBUG ("func-history (0x%x): %d, prev: [%u; %u[", flags, size, begin, end); if (context == 0) error (_("Bad record function-call-history-size.")); /* We start at the end. */ if (end < begin) { /* Truncate the context, if necessary. */ context = min (context, last); end = last; begin = end - context; } else if (size < 0) { if (begin == 0) { printf_unfiltered (_("At the start of the branch trace record.\n")); btinfo->func_iterator.end = 0; return; } /* Truncate the context, if necessary. */ context = min (context, begin); end = begin; begin -= context; } else { if (end == last) { printf_unfiltered (_("At the end of the branch trace record.\n")); btinfo->func_iterator.begin = last; return; } /* Truncate the context, if necessary. */ context = min (context, last - end); begin = end; end += context; } btrace_func_history (btinfo, uiout, begin, end, flags); btinfo->func_iterator.begin = begin; btinfo->func_iterator.end = end; do_cleanups (uiout_cleanup); }
static void record_btrace_call_history (struct target_ops *self, int size, int flags) { struct btrace_thread_info *btinfo; struct btrace_call_history *history; struct btrace_call_iterator begin, end; struct cleanup *uiout_cleanup; struct ui_out *uiout; unsigned int context, covered; uiout = current_uiout; uiout_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, "insn history"); context = abs (size); if (context == 0) error (_("Bad record function-call-history-size.")); btinfo = require_btrace (); history = btinfo->call_history; if (history == NULL) { struct btrace_insn_iterator *replay; DEBUG ("call-history (0x%x): %d", flags, size); /* If we're replaying, we start at the replay position. Otherwise, we start at the tail of the trace. */ replay = btinfo->replay; if (replay != NULL) { begin.function = replay->function; begin.btinfo = btinfo; } else btrace_call_end (&begin, btinfo); /* We start from here and expand in the requested direction. Then we expand in the other direction, as well, to fill up any remaining context. */ end = begin; if (size < 0) { /* We want the current position covered, as well. */ covered = btrace_call_next (&end, 1); covered += btrace_call_prev (&begin, context - covered); covered += btrace_call_next (&end, context - covered); } else { covered = btrace_call_next (&end, context); covered += btrace_call_prev (&begin, context- covered); } } else { begin = history->begin; end = history->end; DEBUG ("call-history (0x%x): %d, prev: [%u; %u)", flags, size, btrace_call_number (&begin), btrace_call_number (&end)); if (size < 0) { end = begin; covered = btrace_call_prev (&begin, context); } else { begin = end; covered = btrace_call_next (&end, context); } } if (covered > 0) btrace_call_history (uiout, btinfo, &begin, &end, flags); else { if (size < 0) printf_unfiltered (_("At the start of the branch trace record.\n")); else printf_unfiltered (_("At the end of the branch trace record.\n")); } btrace_set_call_history (btinfo, &begin, &end); do_cleanups (uiout_cleanup); }