1 /* Branch trace support for GDB, the GNU debugger.
2
3 Copyright (C) 2013-2024 Free Software Foundation, Inc.
4
5 Contributed by Intel Corp. <markus.t.metzger@intel.com>
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21
22 #include "btrace.h"
23 #include "gdbthread.h"
24 #include "inferior.h"
25 #include "target.h"
26 #include "record.h"
27 #include "symtab.h"
28 #include "disasm.h"
29 #include "source.h"
30 #include "filenames.h"
31 #include "regcache.h"
32 #include "gdbsupport/rsp-low.h"
33 #include "cli/cli-cmds.h"
34 #include "cli/cli-utils.h"
35 #include "gdbarch.h"
36
37 /* For maintenance commands. */
38 #include "record-btrace.h"
39
40 #include <inttypes.h>
41 #include <ctype.h>
42 #include <algorithm>
43
44 /* Command lists for btrace maintenance commands. */
45 static struct cmd_list_element *maint_btrace_cmdlist;
46 static struct cmd_list_element *maint_btrace_set_cmdlist;
47 static struct cmd_list_element *maint_btrace_show_cmdlist;
48 static struct cmd_list_element *maint_btrace_pt_set_cmdlist;
49 static struct cmd_list_element *maint_btrace_pt_show_cmdlist;
50
51 /* Control whether to skip PAD packets when computing the packet history. */
52 static bool maint_btrace_pt_skip_pad = true;
53
54 static void btrace_add_pc (struct thread_info *tp);
55
56 /* Print a record debug message. Use do ... while (0) to avoid ambiguities
57 when used in if statements. */
58
59 #define DEBUG(msg, args...) \
60 do \
61 { \
62 if (record_debug != 0) \
63 gdb_printf (gdb_stdlog, \
64 "[btrace] " msg "\n", ##args); \
65 } \
66 while (0)
67
68 #define DEBUG_FTRACE(msg, args...) DEBUG ("[ftrace] " msg, ##args)
69
70 /* Return the function name of a recorded function segment for printing.
71 This function never returns NULL. */
72
73 static const char *
ftrace_print_function_name(const struct btrace_function * bfun)74 ftrace_print_function_name (const struct btrace_function *bfun)
75 {
76 struct minimal_symbol *msym;
77 struct symbol *sym;
78
79 msym = bfun->msym;
80 sym = bfun->sym;
81
82 if (sym != NULL)
83 return sym->print_name ();
84
85 if (msym != NULL)
86 return msym->print_name ();
87
88 return "<unknown>";
89 }
90
91 /* Return the file name of a recorded function segment for printing.
92 This function never returns NULL. */
93
94 static const char *
ftrace_print_filename(const struct btrace_function * bfun)95 ftrace_print_filename (const struct btrace_function *bfun)
96 {
97 struct symbol *sym;
98 const char *filename;
99
100 sym = bfun->sym;
101
102 if (sym != NULL)
103 filename = symtab_to_filename_for_display (sym->symtab ());
104 else
105 filename = "<unknown>";
106
107 return filename;
108 }
109
110 /* Return a string representation of the address of an instruction.
111 This function never returns NULL. */
112
113 static const char *
ftrace_print_insn_addr(const struct btrace_insn * insn)114 ftrace_print_insn_addr (const struct btrace_insn *insn)
115 {
116 if (insn == NULL)
117 return "<nil>";
118
119 return core_addr_to_string_nz (insn->pc);
120 }
121
122 /* Print an ftrace debug status message. */
123
124 static void
ftrace_debug(const struct btrace_function * bfun,const char * prefix)125 ftrace_debug (const struct btrace_function *bfun, const char *prefix)
126 {
127 const char *fun, *file;
128 unsigned int ibegin, iend;
129 int level;
130
131 fun = ftrace_print_function_name (bfun);
132 file = ftrace_print_filename (bfun);
133 level = bfun->level;
134
135 ibegin = bfun->insn_offset;
136 iend = ibegin + bfun->insn.size ();
137
138 DEBUG_FTRACE ("%s: fun = %s, file = %s, level = %d, insn = [%u; %u)",
139 prefix, fun, file, level, ibegin, iend);
140 }
141
142 /* Return the number of instructions in a given function call segment. */
143
144 static unsigned int
ftrace_call_num_insn(const struct btrace_function * bfun)145 ftrace_call_num_insn (const struct btrace_function* bfun)
146 {
147 if (bfun == NULL)
148 return 0;
149
150 /* A gap is always counted as one instruction. */
151 if (bfun->errcode != 0)
152 return 1;
153
154 return bfun->insn.size ();
155 }
156
157 /* Return the function segment with the given NUMBER or NULL if no such segment
158 exists. BTINFO is the branch trace information for the current thread. */
159
160 static struct btrace_function *
ftrace_find_call_by_number(struct btrace_thread_info * btinfo,unsigned int number)161 ftrace_find_call_by_number (struct btrace_thread_info *btinfo,
162 unsigned int number)
163 {
164 if (number == 0 || number > btinfo->functions.size ())
165 return NULL;
166
167 return &btinfo->functions[number - 1];
168 }
169
170 /* A const version of the function above. */
171
172 static const struct btrace_function *
ftrace_find_call_by_number(const struct btrace_thread_info * btinfo,unsigned int number)173 ftrace_find_call_by_number (const struct btrace_thread_info *btinfo,
174 unsigned int number)
175 {
176 if (number == 0 || number > btinfo->functions.size ())
177 return NULL;
178
179 return &btinfo->functions[number - 1];
180 }
181
182 /* Return non-zero if BFUN does not match MFUN and FUN,
183 return zero otherwise. */
184
185 static int
ftrace_function_switched(const struct btrace_function * bfun,const struct minimal_symbol * mfun,const struct symbol * fun)186 ftrace_function_switched (const struct btrace_function *bfun,
187 const struct minimal_symbol *mfun,
188 const struct symbol *fun)
189 {
190 struct minimal_symbol *msym;
191 struct symbol *sym;
192
193 msym = bfun->msym;
194 sym = bfun->sym;
195
196 /* If the minimal symbol changed, we certainly switched functions. */
197 if (mfun != NULL && msym != NULL
198 && strcmp (mfun->linkage_name (), msym->linkage_name ()) != 0)
199 return 1;
200
201 /* If the symbol changed, we certainly switched functions. */
202 if (fun != NULL && sym != NULL)
203 {
204 const char *bfname, *fname;
205
206 /* Check the function name. */
207 if (strcmp (fun->linkage_name (), sym->linkage_name ()) != 0)
208 return 1;
209
210 /* Check the location of those functions, as well. */
211 bfname = symtab_to_fullname (sym->symtab ());
212 fname = symtab_to_fullname (fun->symtab ());
213 if (filename_cmp (fname, bfname) != 0)
214 return 1;
215 }
216
217 /* If we lost symbol information, we switched functions. */
218 if (!(msym == NULL && sym == NULL) && mfun == NULL && fun == NULL)
219 return 1;
220
221 /* If we gained symbol information, we switched functions. */
222 if (msym == NULL && sym == NULL && !(mfun == NULL && fun == NULL))
223 return 1;
224
225 return 0;
226 }
227
228 /* Allocate and initialize a new branch trace function segment at the end of
229 the trace.
230 BTINFO is the branch trace information for the current thread.
231 MFUN and FUN are the symbol information we have for this function.
232 This invalidates all struct btrace_function pointer currently held. */
233
234 static struct btrace_function *
ftrace_new_function(struct btrace_thread_info * btinfo,struct minimal_symbol * mfun,struct symbol * fun)235 ftrace_new_function (struct btrace_thread_info *btinfo,
236 struct minimal_symbol *mfun,
237 struct symbol *fun)
238 {
239 int level;
240 unsigned int number, insn_offset;
241
242 if (btinfo->functions.empty ())
243 {
244 /* Start counting NUMBER and INSN_OFFSET at one. */
245 level = 0;
246 number = 1;
247 insn_offset = 1;
248 }
249 else
250 {
251 const struct btrace_function *prev = &btinfo->functions.back ();
252 level = prev->level;
253 number = prev->number + 1;
254 insn_offset = prev->insn_offset + ftrace_call_num_insn (prev);
255 }
256
257 return &btinfo->functions.emplace_back (mfun, fun, number, insn_offset,
258 level);
259 }
260
261 /* Update the UP field of a function segment. */
262
263 static void
ftrace_update_caller(struct btrace_function * bfun,struct btrace_function * caller,btrace_function_flags flags)264 ftrace_update_caller (struct btrace_function *bfun,
265 struct btrace_function *caller,
266 btrace_function_flags flags)
267 {
268 if (bfun->up != 0)
269 ftrace_debug (bfun, "updating caller");
270
271 bfun->up = caller->number;
272 bfun->flags = flags;
273
274 ftrace_debug (bfun, "set caller");
275 ftrace_debug (caller, "..to");
276 }
277
278 /* Fix up the caller for all segments of a function. */
279
280 static void
ftrace_fixup_caller(struct btrace_thread_info * btinfo,struct btrace_function * bfun,struct btrace_function * caller,btrace_function_flags flags)281 ftrace_fixup_caller (struct btrace_thread_info *btinfo,
282 struct btrace_function *bfun,
283 struct btrace_function *caller,
284 btrace_function_flags flags)
285 {
286 unsigned int prev, next;
287
288 prev = bfun->prev;
289 next = bfun->next;
290 ftrace_update_caller (bfun, caller, flags);
291
292 /* Update all function segments belonging to the same function. */
293 for (; prev != 0; prev = bfun->prev)
294 {
295 bfun = ftrace_find_call_by_number (btinfo, prev);
296 ftrace_update_caller (bfun, caller, flags);
297 }
298
299 for (; next != 0; next = bfun->next)
300 {
301 bfun = ftrace_find_call_by_number (btinfo, next);
302 ftrace_update_caller (bfun, caller, flags);
303 }
304 }
305
306 /* Add a new function segment for a call at the end of the trace.
307 BTINFO is the branch trace information for the current thread.
308 MFUN and FUN are the symbol information we have for this function. */
309
310 static struct btrace_function *
ftrace_new_call(struct btrace_thread_info * btinfo,struct minimal_symbol * mfun,struct symbol * fun)311 ftrace_new_call (struct btrace_thread_info *btinfo,
312 struct minimal_symbol *mfun,
313 struct symbol *fun)
314 {
315 const unsigned int length = btinfo->functions.size ();
316 struct btrace_function *bfun = ftrace_new_function (btinfo, mfun, fun);
317
318 bfun->up = length;
319 bfun->level += 1;
320
321 ftrace_debug (bfun, "new call");
322
323 return bfun;
324 }
325
326 /* Add a new function segment for a tail call at the end of the trace.
327 BTINFO is the branch trace information for the current thread.
328 MFUN and FUN are the symbol information we have for this function. */
329
330 static struct btrace_function *
ftrace_new_tailcall(struct btrace_thread_info * btinfo,struct minimal_symbol * mfun,struct symbol * fun)331 ftrace_new_tailcall (struct btrace_thread_info *btinfo,
332 struct minimal_symbol *mfun,
333 struct symbol *fun)
334 {
335 const unsigned int length = btinfo->functions.size ();
336 struct btrace_function *bfun = ftrace_new_function (btinfo, mfun, fun);
337
338 bfun->up = length;
339 bfun->level += 1;
340 bfun->flags |= BFUN_UP_LINKS_TO_TAILCALL;
341
342 ftrace_debug (bfun, "new tail call");
343
344 return bfun;
345 }
346
347 /* Return the caller of BFUN or NULL if there is none. This function skips
348 tail calls in the call chain. BTINFO is the branch trace information for
349 the current thread. */
350 static struct btrace_function *
ftrace_get_caller(struct btrace_thread_info * btinfo,struct btrace_function * bfun)351 ftrace_get_caller (struct btrace_thread_info *btinfo,
352 struct btrace_function *bfun)
353 {
354 for (; bfun != NULL; bfun = ftrace_find_call_by_number (btinfo, bfun->up))
355 if ((bfun->flags & BFUN_UP_LINKS_TO_TAILCALL) == 0)
356 return ftrace_find_call_by_number (btinfo, bfun->up);
357
358 return NULL;
359 }
360
361 /* Find the innermost caller in the back trace of BFUN with MFUN/FUN
362 symbol information. BTINFO is the branch trace information for the current
363 thread. */
364
365 static struct btrace_function *
ftrace_find_caller(struct btrace_thread_info * btinfo,struct btrace_function * bfun,struct minimal_symbol * mfun,struct symbol * fun)366 ftrace_find_caller (struct btrace_thread_info *btinfo,
367 struct btrace_function *bfun,
368 struct minimal_symbol *mfun,
369 struct symbol *fun)
370 {
371 for (; bfun != NULL; bfun = ftrace_find_call_by_number (btinfo, bfun->up))
372 {
373 /* Skip functions with incompatible symbol information. */
374 if (ftrace_function_switched (bfun, mfun, fun))
375 continue;
376
377 /* This is the function segment we're looking for. */
378 break;
379 }
380
381 return bfun;
382 }
383
384 /* Find the innermost caller in the back trace of BFUN, skipping all
385 function segments that do not end with a call instruction (e.g.
386 tail calls ending with a jump). BTINFO is the branch trace information for
387 the current thread. */
388
389 static struct btrace_function *
ftrace_find_call(struct btrace_thread_info * btinfo,struct btrace_function * bfun)390 ftrace_find_call (struct btrace_thread_info *btinfo,
391 struct btrace_function *bfun)
392 {
393 for (; bfun != NULL; bfun = ftrace_find_call_by_number (btinfo, bfun->up))
394 {
395 /* Skip gaps. */
396 if (bfun->errcode != 0)
397 continue;
398
399 btrace_insn &last = bfun->insn.back ();
400
401 if (last.iclass == BTRACE_INSN_CALL)
402 break;
403 }
404
405 return bfun;
406 }
407
408 /* Add a continuation segment for a function into which we return at the end of
409 the trace.
410 BTINFO is the branch trace information for the current thread.
411 MFUN and FUN are the symbol information we have for this function. */
412
413 static struct btrace_function *
ftrace_new_return(struct btrace_thread_info * btinfo,struct minimal_symbol * mfun,struct symbol * fun)414 ftrace_new_return (struct btrace_thread_info *btinfo,
415 struct minimal_symbol *mfun,
416 struct symbol *fun)
417 {
418 struct btrace_function *prev, *bfun, *caller;
419
420 bfun = ftrace_new_function (btinfo, mfun, fun);
421 prev = ftrace_find_call_by_number (btinfo, bfun->number - 1);
422
423 /* It is important to start at PREV's caller. Otherwise, we might find
424 PREV itself, if PREV is a recursive function. */
425 caller = ftrace_find_call_by_number (btinfo, prev->up);
426 caller = ftrace_find_caller (btinfo, caller, mfun, fun);
427 if (caller != NULL)
428 {
429 /* The caller of PREV is the preceding btrace function segment in this
430 function instance. */
431 gdb_assert (caller->next == 0);
432
433 caller->next = bfun->number;
434 bfun->prev = caller->number;
435
436 /* Maintain the function level. */
437 bfun->level = caller->level;
438
439 /* Maintain the call stack. */
440 bfun->up = caller->up;
441 bfun->flags = caller->flags;
442
443 ftrace_debug (bfun, "new return");
444 }
445 else
446 {
447 /* We did not find a caller. This could mean that something went
448 wrong or that the call is simply not included in the trace. */
449
450 /* Let's search for some actual call. */
451 caller = ftrace_find_call_by_number (btinfo, prev->up);
452 caller = ftrace_find_call (btinfo, caller);
453 if (caller == NULL)
454 {
455 /* There is no call in PREV's back trace. We assume that the
456 branch trace did not include it. */
457
458 /* Let's find the topmost function and add a new caller for it.
459 This should handle a series of initial tail calls. */
460 while (prev->up != 0)
461 prev = ftrace_find_call_by_number (btinfo, prev->up);
462
463 bfun->level = prev->level - 1;
464
465 /* Fix up the call stack for PREV. */
466 ftrace_fixup_caller (btinfo, prev, bfun, BFUN_UP_LINKS_TO_RET);
467
468 ftrace_debug (bfun, "new return - no caller");
469 }
470 else
471 {
472 /* There is a call in PREV's back trace to which we should have
473 returned but didn't. Let's start a new, separate back trace
474 from PREV's level. */
475 bfun->level = prev->level - 1;
476
477 /* We fix up the back trace for PREV but leave other function segments
478 on the same level as they are.
479 This should handle things like schedule () correctly where we're
480 switching contexts. */
481 prev->up = bfun->number;
482 prev->flags = BFUN_UP_LINKS_TO_RET;
483
484 ftrace_debug (bfun, "new return - unknown caller");
485 }
486 }
487
488 return bfun;
489 }
490
491 /* Add a new function segment for a function switch at the end of the trace.
492 BTINFO is the branch trace information for the current thread.
493 MFUN and FUN are the symbol information we have for this function. */
494
495 static struct btrace_function *
ftrace_new_switch(struct btrace_thread_info * btinfo,struct minimal_symbol * mfun,struct symbol * fun)496 ftrace_new_switch (struct btrace_thread_info *btinfo,
497 struct minimal_symbol *mfun,
498 struct symbol *fun)
499 {
500 struct btrace_function *prev, *bfun;
501
502 /* This is an unexplained function switch. We can't really be sure about the
503 call stack, yet the best I can think of right now is to preserve it. */
504 bfun = ftrace_new_function (btinfo, mfun, fun);
505 prev = ftrace_find_call_by_number (btinfo, bfun->number - 1);
506 bfun->up = prev->up;
507 bfun->flags = prev->flags;
508
509 ftrace_debug (bfun, "new switch");
510
511 return bfun;
512 }
513
514 /* Add a new function segment for a gap in the trace due to a decode error at
515 the end of the trace.
516 BTINFO is the branch trace information for the current thread.
517 ERRCODE is the format-specific error code. */
518
519 static struct btrace_function *
ftrace_new_gap(struct btrace_thread_info * btinfo,int errcode,std::vector<unsigned int> & gaps)520 ftrace_new_gap (struct btrace_thread_info *btinfo, int errcode,
521 std::vector<unsigned int> &gaps)
522 {
523 struct btrace_function *bfun;
524
525 if (btinfo->functions.empty ())
526 bfun = ftrace_new_function (btinfo, NULL, NULL);
527 else
528 {
529 /* We hijack the previous function segment if it was empty. */
530 bfun = &btinfo->functions.back ();
531 if (bfun->errcode != 0 || !bfun->insn.empty ())
532 bfun = ftrace_new_function (btinfo, NULL, NULL);
533 }
534
535 bfun->errcode = errcode;
536 gaps.push_back (bfun->number);
537
538 ftrace_debug (bfun, "new gap");
539
540 return bfun;
541 }
542
543 /* Update the current function segment at the end of the trace in BTINFO with
544 respect to the instruction at PC. This may create new function segments.
545 Return the chronologically latest function segment, never NULL. */
546
547 static struct btrace_function *
ftrace_update_function(struct btrace_thread_info * btinfo,CORE_ADDR pc)548 ftrace_update_function (struct btrace_thread_info *btinfo, CORE_ADDR pc)
549 {
550 struct bound_minimal_symbol bmfun;
551 struct minimal_symbol *mfun;
552 struct symbol *fun;
553 struct btrace_function *bfun;
554
555 /* Try to determine the function we're in. We use both types of symbols
556 to avoid surprises when we sometimes get a full symbol and sometimes
557 only a minimal symbol. */
558 fun = find_pc_function (pc);
559 bmfun = lookup_minimal_symbol_by_pc (pc);
560 mfun = bmfun.minsym;
561
562 if (fun == NULL && mfun == NULL)
563 DEBUG_FTRACE ("no symbol at %s", core_addr_to_string_nz (pc));
564
565 /* If we didn't have a function, we create one. */
566 if (btinfo->functions.empty ())
567 return ftrace_new_function (btinfo, mfun, fun);
568
569 /* If we had a gap before, we create a function. */
570 bfun = &btinfo->functions.back ();
571 if (bfun->errcode != 0)
572 return ftrace_new_function (btinfo, mfun, fun);
573
574 /* Check the last instruction, if we have one.
575 We do this check first, since it allows us to fill in the call stack
576 links in addition to the normal flow links. */
577 btrace_insn *last = NULL;
578 if (!bfun->insn.empty ())
579 last = &bfun->insn.back ();
580
581 if (last != NULL)
582 {
583 switch (last->iclass)
584 {
585 case BTRACE_INSN_RETURN:
586 {
587 const char *fname;
588
589 /* On some systems, _dl_runtime_resolve returns to the resolved
590 function instead of jumping to it. From our perspective,
591 however, this is a tailcall.
592 If we treated it as return, we wouldn't be able to find the
593 resolved function in our stack back trace. Hence, we would
594 lose the current stack back trace and start anew with an empty
595 back trace. When the resolved function returns, we would then
596 create a stack back trace with the same function names but
597 different frame id's. This will confuse stepping. */
598 fname = ftrace_print_function_name (bfun);
599 if (strcmp (fname, "_dl_runtime_resolve") == 0)
600 return ftrace_new_tailcall (btinfo, mfun, fun);
601
602 return ftrace_new_return (btinfo, mfun, fun);
603 }
604
605 case BTRACE_INSN_CALL:
606 /* Ignore calls to the next instruction. They are used for PIC. */
607 if (last->pc + last->size == pc)
608 break;
609
610 return ftrace_new_call (btinfo, mfun, fun);
611
612 case BTRACE_INSN_JUMP:
613 {
614 CORE_ADDR start;
615
616 start = get_pc_function_start (pc);
617
618 /* A jump to the start of a function is (typically) a tail call. */
619 if (start == pc)
620 return ftrace_new_tailcall (btinfo, mfun, fun);
621
622 /* Some versions of _Unwind_RaiseException use an indirect
623 jump to 'return' to the exception handler of the caller
624 handling the exception instead of a return. Let's restrict
625 this heuristic to that and related functions. */
626 const char *fname = ftrace_print_function_name (bfun);
627 if (strncmp (fname, "_Unwind_", strlen ("_Unwind_")) == 0)
628 {
629 struct btrace_function *caller
630 = ftrace_find_call_by_number (btinfo, bfun->up);
631 caller = ftrace_find_caller (btinfo, caller, mfun, fun);
632 if (caller != NULL)
633 return ftrace_new_return (btinfo, mfun, fun);
634 }
635
636 /* If we can't determine the function for PC, we treat a jump at
637 the end of the block as tail call if we're switching functions
638 and as an intra-function branch if we don't. */
639 if (start == 0 && ftrace_function_switched (bfun, mfun, fun))
640 return ftrace_new_tailcall (btinfo, mfun, fun);
641
642 break;
643 }
644 }
645 }
646
647 /* Check if we're switching functions for some other reason. */
648 if (ftrace_function_switched (bfun, mfun, fun))
649 {
650 DEBUG_FTRACE ("switching from %s in %s at %s",
651 ftrace_print_insn_addr (last),
652 ftrace_print_function_name (bfun),
653 ftrace_print_filename (bfun));
654
655 return ftrace_new_switch (btinfo, mfun, fun);
656 }
657
658 return bfun;
659 }
660
661 /* Add the instruction at PC to BFUN's instructions. */
662
663 static void
ftrace_update_insns(struct btrace_function * bfun,const btrace_insn & insn)664 ftrace_update_insns (struct btrace_function *bfun, const btrace_insn &insn)
665 {
666 bfun->insn.push_back (insn);
667
668 if (record_debug > 1)
669 ftrace_debug (bfun, "update insn");
670 }
671
672 /* Classify the instruction at PC. */
673
674 static enum btrace_insn_class
ftrace_classify_insn(struct gdbarch * gdbarch,CORE_ADDR pc)675 ftrace_classify_insn (struct gdbarch *gdbarch, CORE_ADDR pc)
676 {
677 enum btrace_insn_class iclass;
678
679 iclass = BTRACE_INSN_OTHER;
680 try
681 {
682 if (gdbarch_insn_is_call (gdbarch, pc))
683 iclass = BTRACE_INSN_CALL;
684 else if (gdbarch_insn_is_ret (gdbarch, pc))
685 iclass = BTRACE_INSN_RETURN;
686 else if (gdbarch_insn_is_jump (gdbarch, pc))
687 iclass = BTRACE_INSN_JUMP;
688 }
689 catch (const gdb_exception_error &error)
690 {
691 }
692
693 return iclass;
694 }
695
696 /* Try to match the back trace at LHS to the back trace at RHS. Returns the
697 number of matching function segments or zero if the back traces do not
698 match. BTINFO is the branch trace information for the current thread. */
699
700 static int
ftrace_match_backtrace(struct btrace_thread_info * btinfo,struct btrace_function * lhs,struct btrace_function * rhs)701 ftrace_match_backtrace (struct btrace_thread_info *btinfo,
702 struct btrace_function *lhs,
703 struct btrace_function *rhs)
704 {
705 int matches;
706
707 for (matches = 0; lhs != NULL && rhs != NULL; ++matches)
708 {
709 if (ftrace_function_switched (lhs, rhs->msym, rhs->sym))
710 return 0;
711
712 lhs = ftrace_get_caller (btinfo, lhs);
713 rhs = ftrace_get_caller (btinfo, rhs);
714 }
715
716 return matches;
717 }
718
719 /* Add ADJUSTMENT to the level of BFUN and succeeding function segments.
720 BTINFO is the branch trace information for the current thread. */
721
722 static void
ftrace_fixup_level(struct btrace_thread_info * btinfo,struct btrace_function * bfun,int adjustment)723 ftrace_fixup_level (struct btrace_thread_info *btinfo,
724 struct btrace_function *bfun, int adjustment)
725 {
726 if (adjustment == 0)
727 return;
728
729 DEBUG_FTRACE ("fixup level (%+d)", adjustment);
730 ftrace_debug (bfun, "..bfun");
731
732 while (bfun != NULL)
733 {
734 bfun->level += adjustment;
735 bfun = ftrace_find_call_by_number (btinfo, bfun->number + 1);
736 }
737 }
738
739 /* Recompute the global level offset. Traverse the function trace and compute
740 the global level offset as the negative of the minimal function level. */
741
742 static void
ftrace_compute_global_level_offset(struct btrace_thread_info * btinfo)743 ftrace_compute_global_level_offset (struct btrace_thread_info *btinfo)
744 {
745 int level = INT_MAX;
746
747 if (btinfo == NULL)
748 return;
749
750 if (btinfo->functions.empty ())
751 return;
752
753 unsigned int length = btinfo->functions.size() - 1;
754 for (unsigned int i = 0; i < length; ++i)
755 level = std::min (level, btinfo->functions[i].level);
756
757 /* The last function segment contains the current instruction, which is not
758 really part of the trace. If it contains just this one instruction, we
759 ignore the segment. */
760 struct btrace_function *last = &btinfo->functions.back();
761 if (last->insn.size () != 1)
762 level = std::min (level, last->level);
763
764 DEBUG_FTRACE ("setting global level offset: %d", -level);
765 btinfo->level = -level;
766 }
767
768 /* Connect the function segments PREV and NEXT in a bottom-to-top walk as in
769 ftrace_connect_backtrace. BTINFO is the branch trace information for the
770 current thread. */
771
772 static void
ftrace_connect_bfun(struct btrace_thread_info * btinfo,struct btrace_function * prev,struct btrace_function * next)773 ftrace_connect_bfun (struct btrace_thread_info *btinfo,
774 struct btrace_function *prev,
775 struct btrace_function *next)
776 {
777 DEBUG_FTRACE ("connecting...");
778 ftrace_debug (prev, "..prev");
779 ftrace_debug (next, "..next");
780
781 /* The function segments are not yet connected. */
782 gdb_assert (prev->next == 0);
783 gdb_assert (next->prev == 0);
784
785 prev->next = next->number;
786 next->prev = prev->number;
787
788 /* We may have moved NEXT to a different function level. */
789 ftrace_fixup_level (btinfo, next, prev->level - next->level);
790
791 /* If we run out of back trace for one, let's use the other's. */
792 if (prev->up == 0)
793 {
794 const btrace_function_flags flags = next->flags;
795
796 next = ftrace_find_call_by_number (btinfo, next->up);
797 if (next != NULL)
798 {
799 DEBUG_FTRACE ("using next's callers");
800 ftrace_fixup_caller (btinfo, prev, next, flags);
801 }
802 }
803 else if (next->up == 0)
804 {
805 const btrace_function_flags flags = prev->flags;
806
807 prev = ftrace_find_call_by_number (btinfo, prev->up);
808 if (prev != NULL)
809 {
810 DEBUG_FTRACE ("using prev's callers");
811 ftrace_fixup_caller (btinfo, next, prev, flags);
812 }
813 }
814 else
815 {
816 /* PREV may have a tailcall caller, NEXT can't. If it does, fixup the up
817 link to add the tail callers to NEXT's back trace.
818
819 This removes NEXT->UP from NEXT's back trace. It will be added back
820 when connecting NEXT and PREV's callers - provided they exist.
821
822 If PREV's back trace consists of a series of tail calls without an
823 actual call, there will be no further connection and NEXT's caller will
824 be removed for good. To catch this case, we handle it here and connect
825 the top of PREV's back trace to NEXT's caller. */
826 if ((prev->flags & BFUN_UP_LINKS_TO_TAILCALL) != 0)
827 {
828 struct btrace_function *caller;
829 btrace_function_flags next_flags, prev_flags;
830
831 /* We checked NEXT->UP above so CALLER can't be NULL. */
832 caller = ftrace_find_call_by_number (btinfo, next->up);
833 next_flags = next->flags;
834 prev_flags = prev->flags;
835
836 DEBUG_FTRACE ("adding prev's tail calls to next");
837
838 prev = ftrace_find_call_by_number (btinfo, prev->up);
839 ftrace_fixup_caller (btinfo, next, prev, prev_flags);
840
841 for (; prev != NULL; prev = ftrace_find_call_by_number (btinfo,
842 prev->up))
843 {
844 /* At the end of PREV's back trace, continue with CALLER. */
845 if (prev->up == 0)
846 {
847 DEBUG_FTRACE ("fixing up link for tailcall chain");
848 ftrace_debug (prev, "..top");
849 ftrace_debug (caller, "..up");
850
851 ftrace_fixup_caller (btinfo, prev, caller, next_flags);
852
853 /* If we skipped any tail calls, this may move CALLER to a
854 different function level.
855
856 Note that changing CALLER's level is only OK because we
857 know that this is the last iteration of the bottom-to-top
858 walk in ftrace_connect_backtrace.
859
860 Otherwise we will fix up CALLER's level when we connect it
861 to PREV's caller in the next iteration. */
862 ftrace_fixup_level (btinfo, caller,
863 prev->level - caller->level - 1);
864 break;
865 }
866
867 /* There's nothing to do if we find a real call. */
868 if ((prev->flags & BFUN_UP_LINKS_TO_TAILCALL) == 0)
869 {
870 DEBUG_FTRACE ("will fix up link in next iteration");
871 break;
872 }
873 }
874 }
875 }
876 }
877
878 /* Connect function segments on the same level in the back trace at LHS and RHS.
879 The back traces at LHS and RHS are expected to match according to
880 ftrace_match_backtrace. BTINFO is the branch trace information for the
881 current thread. */
882
883 static void
ftrace_connect_backtrace(struct btrace_thread_info * btinfo,struct btrace_function * lhs,struct btrace_function * rhs)884 ftrace_connect_backtrace (struct btrace_thread_info *btinfo,
885 struct btrace_function *lhs,
886 struct btrace_function *rhs)
887 {
888 while (lhs != NULL && rhs != NULL)
889 {
890 struct btrace_function *prev, *next;
891
892 gdb_assert (!ftrace_function_switched (lhs, rhs->msym, rhs->sym));
893
894 /* Connecting LHS and RHS may change the up link. */
895 prev = lhs;
896 next = rhs;
897
898 lhs = ftrace_get_caller (btinfo, lhs);
899 rhs = ftrace_get_caller (btinfo, rhs);
900
901 ftrace_connect_bfun (btinfo, prev, next);
902 }
903 }
904
905 /* Bridge the gap between two function segments left and right of a gap if their
906 respective back traces match in at least MIN_MATCHES functions. BTINFO is
907 the branch trace information for the current thread.
908
909 Returns non-zero if the gap could be bridged, zero otherwise. */
910
911 static int
ftrace_bridge_gap(struct btrace_thread_info * btinfo,struct btrace_function * lhs,struct btrace_function * rhs,int min_matches)912 ftrace_bridge_gap (struct btrace_thread_info *btinfo,
913 struct btrace_function *lhs, struct btrace_function *rhs,
914 int min_matches)
915 {
916 struct btrace_function *best_l, *best_r, *cand_l, *cand_r;
917 int best_matches;
918
919 DEBUG_FTRACE ("checking gap at insn %u (req matches: %d)",
920 rhs->insn_offset - 1, min_matches);
921
922 best_matches = 0;
923 best_l = NULL;
924 best_r = NULL;
925
926 /* We search the back traces of LHS and RHS for valid connections and connect
927 the two function segments that give the longest combined back trace. */
928
929 for (cand_l = lhs; cand_l != NULL;
930 cand_l = ftrace_get_caller (btinfo, cand_l))
931 for (cand_r = rhs; cand_r != NULL;
932 cand_r = ftrace_get_caller (btinfo, cand_r))
933 {
934 int matches;
935
936 matches = ftrace_match_backtrace (btinfo, cand_l, cand_r);
937 if (best_matches < matches)
938 {
939 best_matches = matches;
940 best_l = cand_l;
941 best_r = cand_r;
942 }
943 }
944
945 /* We need at least MIN_MATCHES matches. */
946 gdb_assert (min_matches > 0);
947 if (best_matches < min_matches)
948 return 0;
949
950 DEBUG_FTRACE ("..matches: %d", best_matches);
951
952 /* We will fix up the level of BEST_R and succeeding function segments such
953 that BEST_R's level matches BEST_L's when we connect BEST_L to BEST_R.
954
955 This will ignore the level of RHS and following if BEST_R != RHS. I.e. if
956 BEST_R is a successor of RHS in the back trace of RHS (phases 1 and 3).
957
958 To catch this, we already fix up the level here where we can start at RHS
959 instead of at BEST_R. We will ignore the level fixup when connecting
960 BEST_L to BEST_R as they will already be on the same level. */
961 ftrace_fixup_level (btinfo, rhs, best_l->level - best_r->level);
962
963 ftrace_connect_backtrace (btinfo, best_l, best_r);
964
965 return best_matches;
966 }
967
968 /* Try to bridge gaps due to overflow or decode errors by connecting the
969 function segments that are separated by the gap. */
970
971 static void
btrace_bridge_gaps(struct thread_info * tp,std::vector<unsigned int> & gaps)972 btrace_bridge_gaps (struct thread_info *tp, std::vector<unsigned int> &gaps)
973 {
974 struct btrace_thread_info *btinfo = &tp->btrace;
975 std::vector<unsigned int> remaining;
976 int min_matches;
977
978 DEBUG ("bridge gaps");
979
980 /* We require a minimum amount of matches for bridging a gap. The number of
981 required matches will be lowered with each iteration.
982
983 The more matches the higher our confidence that the bridging is correct.
984 For big gaps or small traces, however, it may not be feasible to require a
985 high number of matches. */
986 for (min_matches = 5; min_matches > 0; --min_matches)
987 {
988 /* Let's try to bridge as many gaps as we can. In some cases, we need to
989 skip a gap and revisit it again after we closed later gaps. */
990 while (!gaps.empty ())
991 {
992 for (const unsigned int number : gaps)
993 {
994 struct btrace_function *gap, *lhs, *rhs;
995 int bridged;
996
997 gap = ftrace_find_call_by_number (btinfo, number);
998
999 /* We may have a sequence of gaps if we run from one error into
1000 the next as we try to re-sync onto the trace stream. Ignore
1001 all but the leftmost gap in such a sequence.
1002
1003 Also ignore gaps at the beginning of the trace. */
1004 lhs = ftrace_find_call_by_number (btinfo, gap->number - 1);
1005 if (lhs == NULL || lhs->errcode != 0)
1006 continue;
1007
1008 /* Skip gaps to the right. */
1009 rhs = ftrace_find_call_by_number (btinfo, gap->number + 1);
1010 while (rhs != NULL && rhs->errcode != 0)
1011 rhs = ftrace_find_call_by_number (btinfo, rhs->number + 1);
1012
1013 /* Ignore gaps at the end of the trace. */
1014 if (rhs == NULL)
1015 continue;
1016
1017 bridged = ftrace_bridge_gap (btinfo, lhs, rhs, min_matches);
1018
1019 /* Keep track of gaps we were not able to bridge and try again.
1020 If we just pushed them to the end of GAPS we would risk an
1021 infinite loop in case we simply cannot bridge a gap. */
1022 if (bridged == 0)
1023 remaining.push_back (number);
1024 }
1025
1026 /* Let's see if we made any progress. */
1027 if (remaining.size () == gaps.size ())
1028 break;
1029
1030 gaps.clear ();
1031 gaps.swap (remaining);
1032 }
1033
1034 /* We get here if either GAPS is empty or if GAPS equals REMAINING. */
1035 if (gaps.empty ())
1036 break;
1037
1038 remaining.clear ();
1039 }
1040
1041 /* We may omit this in some cases. Not sure it is worth the extra
1042 complication, though. */
1043 ftrace_compute_global_level_offset (btinfo);
1044 }
1045
1046 /* Compute the function branch trace from BTS trace. */
1047
1048 static void
btrace_compute_ftrace_bts(struct thread_info * tp,const struct btrace_data_bts * btrace,std::vector<unsigned int> & gaps)1049 btrace_compute_ftrace_bts (struct thread_info *tp,
1050 const struct btrace_data_bts *btrace,
1051 std::vector<unsigned int> &gaps)
1052 {
1053 /* We may end up doing target calls that require the current thread to be TP,
1054 for example reading memory through gdb_insn_length. Make sure TP is the
1055 current thread. */
1056 scoped_restore_current_thread restore_thread;
1057 switch_to_thread (tp);
1058
1059 struct btrace_thread_info *btinfo;
1060 unsigned int blk;
1061 int level;
1062
1063 gdbarch *gdbarch = current_inferior ()->arch ();
1064 btinfo = &tp->btrace;
1065 blk = btrace->blocks->size ();
1066
1067 if (btinfo->functions.empty ())
1068 level = INT_MAX;
1069 else
1070 level = -btinfo->level;
1071
1072 while (blk != 0)
1073 {
1074 CORE_ADDR pc;
1075
1076 blk -= 1;
1077
1078 const btrace_block &block = btrace->blocks->at (blk);
1079 pc = block.begin;
1080
1081 for (;;)
1082 {
1083 struct btrace_function *bfun;
1084 struct btrace_insn insn;
1085 int size;
1086
1087 /* We should hit the end of the block. Warn if we went too far. */
1088 if (block.end < pc)
1089 {
1090 /* Indicate the gap in the trace. */
1091 bfun = ftrace_new_gap (btinfo, BDE_BTS_OVERFLOW, gaps);
1092
1093 warning (_("Recorded trace may be corrupted at instruction "
1094 "%u (pc = %s)."), bfun->insn_offset - 1,
1095 core_addr_to_string_nz (pc));
1096
1097 break;
1098 }
1099
1100 bfun = ftrace_update_function (btinfo, pc);
1101
1102 /* Maintain the function level offset.
1103 For all but the last block, we do it here. */
1104 if (blk != 0)
1105 level = std::min (level, bfun->level);
1106
1107 size = 0;
1108 try
1109 {
1110 size = gdb_insn_length (gdbarch, pc);
1111 }
1112 catch (const gdb_exception_error &error)
1113 {
1114 }
1115
1116 insn.pc = pc;
1117 insn.size = size;
1118 insn.iclass = ftrace_classify_insn (gdbarch, pc);
1119 insn.flags = 0;
1120
1121 ftrace_update_insns (bfun, insn);
1122
1123 /* We're done once we pushed the instruction at the end. */
1124 if (block.end == pc)
1125 break;
1126
1127 /* We can't continue if we fail to compute the size. */
1128 if (size <= 0)
1129 {
1130 /* Indicate the gap in the trace. We just added INSN so we're
1131 not at the beginning. */
1132 bfun = ftrace_new_gap (btinfo, BDE_BTS_INSN_SIZE, gaps);
1133
1134 warning (_("Recorded trace may be incomplete at instruction %u "
1135 "(pc = %s)."), bfun->insn_offset - 1,
1136 core_addr_to_string_nz (pc));
1137
1138 break;
1139 }
1140
1141 pc += size;
1142
1143 /* Maintain the function level offset.
1144 For the last block, we do it here to not consider the last
1145 instruction.
1146 Since the last instruction corresponds to the current instruction
1147 and is not really part of the execution history, it shouldn't
1148 affect the level. */
1149 if (blk == 0)
1150 level = std::min (level, bfun->level);
1151 }
1152 }
1153
1154 /* LEVEL is the minimal function level of all btrace function segments.
1155 Define the global level offset to -LEVEL so all function levels are
1156 normalized to start at zero. */
1157 btinfo->level = -level;
1158 }
1159
1160 #if defined (HAVE_LIBIPT)
1161
1162 static enum btrace_insn_class
pt_reclassify_insn(enum pt_insn_class iclass)1163 pt_reclassify_insn (enum pt_insn_class iclass)
1164 {
1165 switch (iclass)
1166 {
1167 case ptic_call:
1168 return BTRACE_INSN_CALL;
1169
1170 case ptic_return:
1171 return BTRACE_INSN_RETURN;
1172
1173 case ptic_jump:
1174 return BTRACE_INSN_JUMP;
1175
1176 default:
1177 return BTRACE_INSN_OTHER;
1178 }
1179 }
1180
1181 /* Return the btrace instruction flags for INSN. */
1182
1183 static btrace_insn_flags
pt_btrace_insn_flags(const struct pt_insn & insn)1184 pt_btrace_insn_flags (const struct pt_insn &insn)
1185 {
1186 btrace_insn_flags flags = 0;
1187
1188 if (insn.speculative)
1189 flags |= BTRACE_INSN_FLAG_SPECULATIVE;
1190
1191 return flags;
1192 }
1193
1194 /* Return the btrace instruction for INSN. */
1195
1196 static btrace_insn
pt_btrace_insn(const struct pt_insn & insn)1197 pt_btrace_insn (const struct pt_insn &insn)
1198 {
1199 return {(CORE_ADDR) insn.ip, (gdb_byte) insn.size,
1200 pt_reclassify_insn (insn.iclass),
1201 pt_btrace_insn_flags (insn)};
1202 }
1203
1204 /* Handle instruction decode events (libipt-v2). */
1205
1206 static int
handle_pt_insn_events(struct btrace_thread_info * btinfo,struct pt_insn_decoder * decoder,std::vector<unsigned int> & gaps,int status)1207 handle_pt_insn_events (struct btrace_thread_info *btinfo,
1208 struct pt_insn_decoder *decoder,
1209 std::vector<unsigned int> &gaps, int status)
1210 {
1211 #if defined (HAVE_PT_INSN_EVENT)
1212 while (status & pts_event_pending)
1213 {
1214 struct btrace_function *bfun;
1215 struct pt_event event;
1216 uint64_t offset;
1217
1218 status = pt_insn_event (decoder, &event, sizeof (event));
1219 if (status < 0)
1220 break;
1221
1222 switch (event.type)
1223 {
1224 default:
1225 break;
1226
1227 case ptev_enabled:
1228 if (event.status_update != 0)
1229 break;
1230
1231 if (event.variant.enabled.resumed == 0 && !btinfo->functions.empty ())
1232 {
1233 bfun = ftrace_new_gap (btinfo, BDE_PT_DISABLED, gaps);
1234
1235 pt_insn_get_offset (decoder, &offset);
1236
1237 warning (_("Non-contiguous trace at instruction %u (offset = 0x%"
1238 PRIx64 ")."), bfun->insn_offset - 1, offset);
1239 }
1240
1241 break;
1242
1243 case ptev_overflow:
1244 bfun = ftrace_new_gap (btinfo, BDE_PT_OVERFLOW, gaps);
1245
1246 pt_insn_get_offset (decoder, &offset);
1247
1248 warning (_("Overflow at instruction %u (offset = 0x%" PRIx64 ")."),
1249 bfun->insn_offset - 1, offset);
1250
1251 break;
1252 }
1253 }
1254 #endif /* defined (HAVE_PT_INSN_EVENT) */
1255
1256 return status;
1257 }
1258
1259 /* Handle events indicated by flags in INSN (libipt-v1). */
1260
1261 static void
handle_pt_insn_event_flags(struct btrace_thread_info * btinfo,struct pt_insn_decoder * decoder,const struct pt_insn & insn,std::vector<unsigned int> & gaps)1262 handle_pt_insn_event_flags (struct btrace_thread_info *btinfo,
1263 struct pt_insn_decoder *decoder,
1264 const struct pt_insn &insn,
1265 std::vector<unsigned int> &gaps)
1266 {
1267 #if defined (HAVE_STRUCT_PT_INSN_ENABLED)
1268 /* Tracing is disabled and re-enabled each time we enter the kernel. Most
1269 times, we continue from the same instruction we stopped before. This is
1270 indicated via the RESUMED instruction flag. The ENABLED instruction flag
1271 means that we continued from some other instruction. Indicate this as a
1272 trace gap except when tracing just started. */
1273 if (insn.enabled && !btinfo->functions.empty ())
1274 {
1275 struct btrace_function *bfun;
1276 uint64_t offset;
1277
1278 bfun = ftrace_new_gap (btinfo, BDE_PT_DISABLED, gaps);
1279
1280 pt_insn_get_offset (decoder, &offset);
1281
1282 warning (_("Non-contiguous trace at instruction %u (offset = 0x%" PRIx64
1283 ", pc = 0x%" PRIx64 ")."), bfun->insn_offset - 1, offset,
1284 insn.ip);
1285 }
1286 #endif /* defined (HAVE_STRUCT_PT_INSN_ENABLED) */
1287
1288 #if defined (HAVE_STRUCT_PT_INSN_RESYNCED)
1289 /* Indicate trace overflows. */
1290 if (insn.resynced)
1291 {
1292 struct btrace_function *bfun;
1293 uint64_t offset;
1294
1295 bfun = ftrace_new_gap (btinfo, BDE_PT_OVERFLOW, gaps);
1296
1297 pt_insn_get_offset (decoder, &offset);
1298
1299 warning (_("Overflow at instruction %u (offset = 0x%" PRIx64 ", pc = 0x%"
1300 PRIx64 ")."), bfun->insn_offset - 1, offset, insn.ip);
1301 }
1302 #endif /* defined (HAVE_STRUCT_PT_INSN_RESYNCED) */
1303 }
1304
1305 /* Add function branch trace to BTINFO using DECODER. */
1306
1307 static void
ftrace_add_pt(struct btrace_thread_info * btinfo,struct pt_insn_decoder * decoder,int * plevel,std::vector<unsigned int> & gaps)1308 ftrace_add_pt (struct btrace_thread_info *btinfo,
1309 struct pt_insn_decoder *decoder,
1310 int *plevel,
1311 std::vector<unsigned int> &gaps)
1312 {
1313 struct btrace_function *bfun;
1314 uint64_t offset;
1315 int status;
1316
1317 for (;;)
1318 {
1319 struct pt_insn insn;
1320
1321 status = pt_insn_sync_forward (decoder);
1322 if (status < 0)
1323 {
1324 if (status != -pte_eos)
1325 warning (_("Failed to synchronize onto the Intel Processor "
1326 "Trace stream: %s."), pt_errstr (pt_errcode (status)));
1327 break;
1328 }
1329
1330 for (;;)
1331 {
1332 /* Handle events from the previous iteration or synchronization. */
1333 status = handle_pt_insn_events (btinfo, decoder, gaps, status);
1334 if (status < 0)
1335 break;
1336
1337 status = pt_insn_next (decoder, &insn, sizeof(insn));
1338 if (status < 0)
1339 break;
1340
1341 /* Handle events indicated by flags in INSN. */
1342 handle_pt_insn_event_flags (btinfo, decoder, insn, gaps);
1343
1344 bfun = ftrace_update_function (btinfo, insn.ip);
1345
1346 /* Maintain the function level offset. */
1347 *plevel = std::min (*plevel, bfun->level);
1348
1349 ftrace_update_insns (bfun, pt_btrace_insn (insn));
1350 }
1351
1352 if (status == -pte_eos)
1353 break;
1354
1355 /* Indicate the gap in the trace. */
1356 bfun = ftrace_new_gap (btinfo, status, gaps);
1357
1358 pt_insn_get_offset (decoder, &offset);
1359
1360 warning (_("Decode error (%d) at instruction %u (offset = 0x%" PRIx64
1361 ", pc = 0x%" PRIx64 "): %s."), status, bfun->insn_offset - 1,
1362 offset, insn.ip, pt_errstr (pt_errcode (status)));
1363 }
1364 }
1365
1366 /* A callback function to allow the trace decoder to read the inferior's
1367 memory. */
1368
1369 static int
btrace_pt_readmem_callback(gdb_byte * buffer,size_t size,const struct pt_asid * asid,uint64_t pc,void * context)1370 btrace_pt_readmem_callback (gdb_byte *buffer, size_t size,
1371 const struct pt_asid *asid, uint64_t pc,
1372 void *context)
1373 {
1374 int result, errcode;
1375
1376 result = (int) size;
1377 try
1378 {
1379 errcode = target_read_code ((CORE_ADDR) pc, buffer, size);
1380 if (errcode != 0)
1381 result = -pte_nomap;
1382 }
1383 catch (const gdb_exception_error &error)
1384 {
1385 result = -pte_nomap;
1386 }
1387
1388 return result;
1389 }
1390
1391 /* Translate the vendor from one enum to another. */
1392
1393 static enum pt_cpu_vendor
pt_translate_cpu_vendor(enum btrace_cpu_vendor vendor)1394 pt_translate_cpu_vendor (enum btrace_cpu_vendor vendor)
1395 {
1396 switch (vendor)
1397 {
1398 default:
1399 return pcv_unknown;
1400
1401 case CV_INTEL:
1402 return pcv_intel;
1403 }
1404 }
1405
1406 /* Finalize the function branch trace after decode. */
1407
btrace_finalize_ftrace_pt(struct pt_insn_decoder * decoder,struct thread_info * tp,int level)1408 static void btrace_finalize_ftrace_pt (struct pt_insn_decoder *decoder,
1409 struct thread_info *tp, int level)
1410 {
1411 pt_insn_free_decoder (decoder);
1412
1413 /* LEVEL is the minimal function level of all btrace function segments.
1414 Define the global level offset to -LEVEL so all function levels are
1415 normalized to start at zero. */
1416 tp->btrace.level = -level;
1417
1418 /* Add a single last instruction entry for the current PC.
1419 This allows us to compute the backtrace at the current PC using both
1420 standard unwind and btrace unwind.
1421 This extra entry is ignored by all record commands. */
1422 btrace_add_pc (tp);
1423 }
1424
1425 /* Compute the function branch trace from Intel Processor Trace
1426 format. */
1427
1428 static void
btrace_compute_ftrace_pt(struct thread_info * tp,const struct btrace_data_pt * btrace,std::vector<unsigned int> & gaps)1429 btrace_compute_ftrace_pt (struct thread_info *tp,
1430 const struct btrace_data_pt *btrace,
1431 std::vector<unsigned int> &gaps)
1432 {
1433 /* We may end up doing target calls that require the current thread to be TP,
1434 for example reading memory through btrace_pt_readmem_callback. Make sure
1435 TP is the current thread. */
1436 scoped_restore_current_thread restore_thread;
1437 switch_to_thread (tp);
1438
1439 struct btrace_thread_info *btinfo;
1440 struct pt_insn_decoder *decoder;
1441 struct pt_config config;
1442 int level, errcode;
1443
1444 if (btrace->size == 0)
1445 return;
1446
1447 btinfo = &tp->btrace;
1448 if (btinfo->functions.empty ())
1449 level = INT_MAX;
1450 else
1451 level = -btinfo->level;
1452
1453 pt_config_init(&config);
1454 config.begin = btrace->data;
1455 config.end = btrace->data + btrace->size;
1456
1457 /* We treat an unknown vendor as 'no errata'. */
1458 if (btrace->config.cpu.vendor != CV_UNKNOWN)
1459 {
1460 config.cpu.vendor
1461 = pt_translate_cpu_vendor (btrace->config.cpu.vendor);
1462 config.cpu.family = btrace->config.cpu.family;
1463 config.cpu.model = btrace->config.cpu.model;
1464 config.cpu.stepping = btrace->config.cpu.stepping;
1465
1466 errcode = pt_cpu_errata (&config.errata, &config.cpu);
1467 if (errcode < 0)
1468 error (_("Failed to configure the Intel Processor Trace "
1469 "decoder: %s."), pt_errstr (pt_errcode (errcode)));
1470 }
1471
1472 decoder = pt_insn_alloc_decoder (&config);
1473 if (decoder == NULL)
1474 error (_("Failed to allocate the Intel Processor Trace decoder."));
1475
1476 try
1477 {
1478 struct pt_image *image;
1479
1480 image = pt_insn_get_image(decoder);
1481 if (image == NULL)
1482 error (_("Failed to configure the Intel Processor Trace decoder."));
1483
1484 errcode = pt_image_set_callback(image, btrace_pt_readmem_callback, NULL);
1485 if (errcode < 0)
1486 error (_("Failed to configure the Intel Processor Trace decoder: "
1487 "%s."), pt_errstr (pt_errcode (errcode)));
1488
1489 ftrace_add_pt (btinfo, decoder, &level, gaps);
1490 }
1491 catch (const gdb_exception &error)
1492 {
1493 /* Indicate a gap in the trace if we quit trace processing. */
1494 if (error.reason == RETURN_QUIT && !btinfo->functions.empty ())
1495 ftrace_new_gap (btinfo, BDE_PT_USER_QUIT, gaps);
1496
1497 btrace_finalize_ftrace_pt (decoder, tp, level);
1498
1499 throw;
1500 }
1501
1502 btrace_finalize_ftrace_pt (decoder, tp, level);
1503 }
1504
1505 #else /* defined (HAVE_LIBIPT) */
1506
1507 static void
btrace_compute_ftrace_pt(struct thread_info * tp,const struct btrace_data_pt * btrace,std::vector<unsigned int> & gaps)1508 btrace_compute_ftrace_pt (struct thread_info *tp,
1509 const struct btrace_data_pt *btrace,
1510 std::vector<unsigned int> &gaps)
1511 {
1512 internal_error (_("Unexpected branch trace format."));
1513 }
1514
1515 #endif /* defined (HAVE_LIBIPT) */
1516
1517 /* Compute the function branch trace from a block branch trace BTRACE for
1518 a thread given by BTINFO. If CPU is not NULL, overwrite the cpu in the
1519 branch trace configuration. This is currently only used for the PT
1520 format. */
1521
1522 static void
btrace_compute_ftrace_1(struct thread_info * tp,struct btrace_data * btrace,const struct btrace_cpu * cpu,std::vector<unsigned int> & gaps)1523 btrace_compute_ftrace_1 (struct thread_info *tp,
1524 struct btrace_data *btrace,
1525 const struct btrace_cpu *cpu,
1526 std::vector<unsigned int> &gaps)
1527 {
1528 DEBUG ("compute ftrace");
1529
1530 switch (btrace->format)
1531 {
1532 case BTRACE_FORMAT_NONE:
1533 return;
1534
1535 case BTRACE_FORMAT_BTS:
1536 btrace_compute_ftrace_bts (tp, &btrace->variant.bts, gaps);
1537 return;
1538
1539 case BTRACE_FORMAT_PT:
1540 /* Overwrite the cpu we use for enabling errata workarounds. */
1541 if (cpu != nullptr)
1542 btrace->variant.pt.config.cpu = *cpu;
1543
1544 btrace_compute_ftrace_pt (tp, &btrace->variant.pt, gaps);
1545 return;
1546 }
1547
1548 internal_error (_("Unknown branch trace format."));
1549 }
1550
1551 static void
btrace_finalize_ftrace(struct thread_info * tp,std::vector<unsigned int> & gaps)1552 btrace_finalize_ftrace (struct thread_info *tp, std::vector<unsigned int> &gaps)
1553 {
1554 if (!gaps.empty ())
1555 {
1556 tp->btrace.ngaps += gaps.size ();
1557 btrace_bridge_gaps (tp, gaps);
1558 }
1559 }
1560
1561 static void
btrace_compute_ftrace(struct thread_info * tp,struct btrace_data * btrace,const struct btrace_cpu * cpu)1562 btrace_compute_ftrace (struct thread_info *tp, struct btrace_data *btrace,
1563 const struct btrace_cpu *cpu)
1564 {
1565 std::vector<unsigned int> gaps;
1566
1567 try
1568 {
1569 btrace_compute_ftrace_1 (tp, btrace, cpu, gaps);
1570 }
1571 catch (const gdb_exception &error)
1572 {
1573 btrace_finalize_ftrace (tp, gaps);
1574
1575 throw;
1576 }
1577
1578 btrace_finalize_ftrace (tp, gaps);
1579 }
1580
1581 /* Add an entry for the current PC. */
1582
1583 static void
btrace_add_pc(struct thread_info * tp)1584 btrace_add_pc (struct thread_info *tp)
1585 {
1586 struct btrace_data btrace;
1587 struct regcache *regcache;
1588 CORE_ADDR pc;
1589
1590 regcache = get_thread_regcache (tp);
1591 pc = regcache_read_pc (regcache);
1592
1593 btrace.format = BTRACE_FORMAT_BTS;
1594 btrace.variant.bts.blocks = new std::vector<btrace_block>;
1595
1596 btrace.variant.bts.blocks->emplace_back (pc, pc);
1597
1598 btrace_compute_ftrace (tp, &btrace, NULL);
1599 }
1600
1601 /* See btrace.h. */
1602
1603 void
btrace_enable(struct thread_info * tp,const struct btrace_config * conf)1604 btrace_enable (struct thread_info *tp, const struct btrace_config *conf)
1605 {
1606 if (tp->btrace.target != NULL)
1607 error (_("Recording already enabled on thread %s (%s)."),
1608 print_thread_id (tp), target_pid_to_str (tp->ptid).c_str ());
1609
1610 #if !defined (HAVE_LIBIPT)
1611 if (conf->format == BTRACE_FORMAT_PT)
1612 error (_("Intel Processor Trace support was disabled at compile time."));
1613 #endif /* !defined (HAVE_LIBIPT) */
1614
1615 DEBUG ("enable thread %s (%s)", print_thread_id (tp),
1616 tp->ptid.to_string ().c_str ());
1617
1618 tp->btrace.target = target_enable_btrace (tp, conf);
1619
1620 if (tp->btrace.target == NULL)
1621 error (_("Failed to enable recording on thread %s (%s)."),
1622 print_thread_id (tp), target_pid_to_str (tp->ptid).c_str ());
1623
1624 /* We need to undo the enable in case of errors. */
1625 try
1626 {
1627 /* Add an entry for the current PC so we start tracing from where we
1628 enabled it.
1629
1630 If we can't access TP's registers, TP is most likely running. In this
1631 case, we can't really say where tracing was enabled so it should be
1632 safe to simply skip this step.
1633
1634 This is not relevant for BTRACE_FORMAT_PT since the trace will already
1635 start at the PC at which tracing was enabled. */
1636 if (conf->format != BTRACE_FORMAT_PT
1637 && can_access_registers_thread (tp))
1638 btrace_add_pc (tp);
1639 }
1640 catch (const gdb_exception &exception)
1641 {
1642 btrace_disable (tp);
1643
1644 throw;
1645 }
1646 }
1647
1648 /* See btrace.h. */
1649
1650 const struct btrace_config *
btrace_conf(const struct btrace_thread_info * btinfo)1651 btrace_conf (const struct btrace_thread_info *btinfo)
1652 {
1653 if (btinfo->target == NULL)
1654 return NULL;
1655
1656 return target_btrace_conf (btinfo->target);
1657 }
1658
1659 /* See btrace.h. */
1660
1661 void
btrace_disable(struct thread_info * tp)1662 btrace_disable (struct thread_info *tp)
1663 {
1664 struct btrace_thread_info *btp = &tp->btrace;
1665
1666 if (btp->target == NULL)
1667 error (_("Recording not enabled on thread %s (%s)."),
1668 print_thread_id (tp), target_pid_to_str (tp->ptid).c_str ());
1669
1670 DEBUG ("disable thread %s (%s)", print_thread_id (tp),
1671 tp->ptid.to_string ().c_str ());
1672
1673 target_disable_btrace (btp->target);
1674 btp->target = NULL;
1675
1676 btrace_clear (tp);
1677 }
1678
1679 /* See btrace.h. */
1680
1681 void
btrace_teardown(struct thread_info * tp)1682 btrace_teardown (struct thread_info *tp)
1683 {
1684 struct btrace_thread_info *btp = &tp->btrace;
1685
1686 if (btp->target == NULL)
1687 return;
1688
1689 DEBUG ("teardown thread %s (%s)", print_thread_id (tp),
1690 tp->ptid.to_string ().c_str ());
1691
1692 target_teardown_btrace (btp->target);
1693 btp->target = NULL;
1694
1695 btrace_clear (tp);
1696 }
1697
1698 /* Stitch branch trace in BTS format. */
1699
1700 static int
btrace_stitch_bts(struct btrace_data_bts * btrace,struct thread_info * tp)1701 btrace_stitch_bts (struct btrace_data_bts *btrace, struct thread_info *tp)
1702 {
1703 struct btrace_thread_info *btinfo;
1704 struct btrace_function *last_bfun;
1705 btrace_block *first_new_block;
1706
1707 btinfo = &tp->btrace;
1708 gdb_assert (!btinfo->functions.empty ());
1709 gdb_assert (!btrace->blocks->empty ());
1710
1711 last_bfun = &btinfo->functions.back ();
1712
1713 /* If the existing trace ends with a gap, we just glue the traces
1714 together. We need to drop the last (i.e. chronologically first) block
1715 of the new trace, though, since we can't fill in the start address.*/
1716 if (last_bfun->insn.empty ())
1717 {
1718 btrace->blocks->pop_back ();
1719 return 0;
1720 }
1721
1722 /* Beware that block trace starts with the most recent block, so the
1723 chronologically first block in the new trace is the last block in
1724 the new trace's block vector. */
1725 first_new_block = &btrace->blocks->back ();
1726 const btrace_insn &last_insn = last_bfun->insn.back ();
1727
1728 /* If the current PC at the end of the block is the same as in our current
1729 trace, there are two explanations:
1730 1. we executed the instruction and some branch brought us back.
1731 2. we have not made any progress.
1732 In the first case, the delta trace vector should contain at least two
1733 entries.
1734 In the second case, the delta trace vector should contain exactly one
1735 entry for the partial block containing the current PC. Remove it. */
1736 if (first_new_block->end == last_insn.pc && btrace->blocks->size () == 1)
1737 {
1738 btrace->blocks->pop_back ();
1739 return 0;
1740 }
1741
1742 DEBUG ("stitching %s to %s", ftrace_print_insn_addr (&last_insn),
1743 core_addr_to_string_nz (first_new_block->end));
1744
1745 /* Do a simple sanity check to make sure we don't accidentally end up
1746 with a bad block. This should not occur in practice. */
1747 if (first_new_block->end < last_insn.pc)
1748 {
1749 warning (_("Error while trying to read delta trace. Falling back to "
1750 "a full read."));
1751 return -1;
1752 }
1753
1754 /* We adjust the last block to start at the end of our current trace. */
1755 gdb_assert (first_new_block->begin == 0);
1756 first_new_block->begin = last_insn.pc;
1757
1758 /* We simply pop the last insn so we can insert it again as part of
1759 the normal branch trace computation.
1760 Since instruction iterators are based on indices in the instructions
1761 vector, we don't leave any pointers dangling. */
1762 DEBUG ("pruning insn at %s for stitching",
1763 ftrace_print_insn_addr (&last_insn));
1764
1765 last_bfun->insn.pop_back ();
1766
1767 /* The instructions vector may become empty temporarily if this has
1768 been the only instruction in this function segment.
1769 This violates the invariant but will be remedied shortly by
1770 btrace_compute_ftrace when we add the new trace. */
1771
1772 /* The only case where this would hurt is if the entire trace consisted
1773 of just that one instruction. If we remove it, we might turn the now
1774 empty btrace function segment into a gap. But we don't want gaps at
1775 the beginning. To avoid this, we remove the entire old trace. */
1776 if (last_bfun->number == 1 && last_bfun->insn.empty ())
1777 btrace_clear (tp);
1778
1779 return 0;
1780 }
1781
1782 /* Adjust the block trace in order to stitch old and new trace together.
1783 BTRACE is the new delta trace between the last and the current stop.
1784 TP is the traced thread.
1785 May modifx BTRACE as well as the existing trace in TP.
1786 Return 0 on success, -1 otherwise. */
1787
1788 static int
btrace_stitch_trace(struct btrace_data * btrace,struct thread_info * tp)1789 btrace_stitch_trace (struct btrace_data *btrace, struct thread_info *tp)
1790 {
1791 /* If we don't have trace, there's nothing to do. */
1792 if (btrace->empty ())
1793 return 0;
1794
1795 switch (btrace->format)
1796 {
1797 case BTRACE_FORMAT_NONE:
1798 return 0;
1799
1800 case BTRACE_FORMAT_BTS:
1801 return btrace_stitch_bts (&btrace->variant.bts, tp);
1802
1803 case BTRACE_FORMAT_PT:
1804 /* Delta reads are not supported. */
1805 return -1;
1806 }
1807
1808 internal_error (_("Unknown branch trace format."));
1809 }
1810
1811 /* Clear the branch trace histories in BTINFO. */
1812
1813 static void
btrace_clear_history(struct btrace_thread_info * btinfo)1814 btrace_clear_history (struct btrace_thread_info *btinfo)
1815 {
1816 xfree (btinfo->insn_history);
1817 xfree (btinfo->call_history);
1818 xfree (btinfo->replay);
1819
1820 btinfo->insn_history = NULL;
1821 btinfo->call_history = NULL;
1822 btinfo->replay = NULL;
1823 }
1824
1825 /* Clear the branch trace maintenance histories in BTINFO. */
1826
1827 static void
btrace_maint_clear(struct btrace_thread_info * btinfo)1828 btrace_maint_clear (struct btrace_thread_info *btinfo)
1829 {
1830 switch (btinfo->data.format)
1831 {
1832 default:
1833 break;
1834
1835 case BTRACE_FORMAT_BTS:
1836 btinfo->maint.variant.bts.packet_history.begin = 0;
1837 btinfo->maint.variant.bts.packet_history.end = 0;
1838 break;
1839
1840 #if defined (HAVE_LIBIPT)
1841 case BTRACE_FORMAT_PT:
1842 delete btinfo->maint.variant.pt.packets;
1843
1844 btinfo->maint.variant.pt.packets = NULL;
1845 btinfo->maint.variant.pt.packet_history.begin = 0;
1846 btinfo->maint.variant.pt.packet_history.end = 0;
1847 break;
1848 #endif /* defined (HAVE_LIBIPT) */
1849 }
1850 }
1851
1852 /* See btrace.h. */
1853
1854 const char *
btrace_decode_error(enum btrace_format format,int errcode)1855 btrace_decode_error (enum btrace_format format, int errcode)
1856 {
1857 switch (format)
1858 {
1859 case BTRACE_FORMAT_BTS:
1860 switch (errcode)
1861 {
1862 case BDE_BTS_OVERFLOW:
1863 return _("instruction overflow");
1864
1865 case BDE_BTS_INSN_SIZE:
1866 return _("unknown instruction");
1867
1868 default:
1869 break;
1870 }
1871 break;
1872
1873 #if defined (HAVE_LIBIPT)
1874 case BTRACE_FORMAT_PT:
1875 switch (errcode)
1876 {
1877 case BDE_PT_USER_QUIT:
1878 return _("trace decode cancelled");
1879
1880 case BDE_PT_DISABLED:
1881 return _("disabled");
1882
1883 case BDE_PT_OVERFLOW:
1884 return _("overflow");
1885
1886 default:
1887 if (errcode < 0)
1888 return pt_errstr (pt_errcode (errcode));
1889 break;
1890 }
1891 break;
1892 #endif /* defined (HAVE_LIBIPT) */
1893
1894 default:
1895 break;
1896 }
1897
1898 return _("unknown");
1899 }
1900
1901 /* See btrace.h. */
1902
1903 void
btrace_fetch(struct thread_info * tp,const struct btrace_cpu * cpu)1904 btrace_fetch (struct thread_info *tp, const struct btrace_cpu *cpu)
1905 {
1906 struct btrace_thread_info *btinfo;
1907 struct btrace_target_info *tinfo;
1908 struct btrace_data btrace;
1909 int errcode;
1910
1911 DEBUG ("fetch thread %s (%s)", print_thread_id (tp),
1912 tp->ptid.to_string ().c_str ());
1913
1914 btinfo = &tp->btrace;
1915 tinfo = btinfo->target;
1916 if (tinfo == NULL)
1917 return;
1918
1919 /* There's no way we could get new trace while replaying.
1920 On the other hand, delta trace would return a partial record with the
1921 current PC, which is the replay PC, not the last PC, as expected. */
1922 if (btinfo->replay != NULL)
1923 return;
1924
1925 /* With CLI usage, TP is always the current thread when we get here.
1926 However, since we can also store a gdb.Record object in Python
1927 referring to a different thread than the current one, we need to
1928 temporarily set the current thread. */
1929 scoped_restore_current_thread restore_thread;
1930 switch_to_thread (tp);
1931
1932 /* We should not be called on running or exited threads. */
1933 gdb_assert (can_access_registers_thread (tp));
1934
1935 /* Let's first try to extend the trace we already have. */
1936 if (!btinfo->functions.empty ())
1937 {
1938 errcode = target_read_btrace (&btrace, tinfo, BTRACE_READ_DELTA);
1939 if (errcode == 0)
1940 {
1941 /* Success. Let's try to stitch the traces together. */
1942 errcode = btrace_stitch_trace (&btrace, tp);
1943 }
1944 else
1945 {
1946 /* We failed to read delta trace. Let's try to read new trace. */
1947 errcode = target_read_btrace (&btrace, tinfo, BTRACE_READ_NEW);
1948
1949 /* If we got any new trace, discard what we have. */
1950 if (errcode == 0 && !btrace.empty ())
1951 btrace_clear (tp);
1952 }
1953
1954 /* If we were not able to read the trace, we start over. */
1955 if (errcode != 0)
1956 {
1957 btrace_clear (tp);
1958 errcode = target_read_btrace (&btrace, tinfo, BTRACE_READ_ALL);
1959 }
1960 }
1961 else
1962 errcode = target_read_btrace (&btrace, tinfo, BTRACE_READ_ALL);
1963
1964 /* If we were not able to read the branch trace, signal an error. */
1965 if (errcode != 0)
1966 error (_("Failed to read branch trace."));
1967
1968 /* Compute the trace, provided we have any. */
1969 if (!btrace.empty ())
1970 {
1971 /* Store the raw trace data. The stored data will be cleared in
1972 btrace_clear, so we always append the new trace. */
1973 btrace_data_append (&btinfo->data, &btrace);
1974 btrace_maint_clear (btinfo);
1975
1976 btrace_clear_history (btinfo);
1977 btrace_compute_ftrace (tp, &btrace, cpu);
1978 }
1979 }
1980
1981 /* See btrace.h. */
1982
1983 void
btrace_clear(struct thread_info * tp)1984 btrace_clear (struct thread_info *tp)
1985 {
1986 struct btrace_thread_info *btinfo;
1987
1988 DEBUG ("clear thread %s (%s)", print_thread_id (tp),
1989 tp->ptid.to_string ().c_str ());
1990
1991 /* Make sure btrace frames that may hold a pointer into the branch
1992 trace data are destroyed. */
1993 reinit_frame_cache ();
1994
1995 btinfo = &tp->btrace;
1996
1997 btinfo->functions.clear ();
1998 btinfo->ngaps = 0;
1999
2000 /* Must clear the maint data before - it depends on BTINFO->DATA. */
2001 btrace_maint_clear (btinfo);
2002 btinfo->data.clear ();
2003 btrace_clear_history (btinfo);
2004 }
2005
2006 /* See btrace.h. */
2007
2008 void
btrace_free_objfile(struct objfile * objfile)2009 btrace_free_objfile (struct objfile *objfile)
2010 {
2011 DEBUG ("free objfile");
2012
2013 for (thread_info *tp : all_non_exited_threads ())
2014 btrace_clear (tp);
2015 }
2016
2017 /* See btrace.h. */
2018
2019 const struct btrace_insn *
btrace_insn_get(const struct btrace_insn_iterator * it)2020 btrace_insn_get (const struct btrace_insn_iterator *it)
2021 {
2022 const struct btrace_function *bfun;
2023 unsigned int index, end;
2024
2025 index = it->insn_index;
2026 bfun = &it->btinfo->functions[it->call_index];
2027
2028 /* Check if the iterator points to a gap in the trace. */
2029 if (bfun->errcode != 0)
2030 return NULL;
2031
2032 /* The index is within the bounds of this function's instruction vector. */
2033 end = bfun->insn.size ();
2034 gdb_assert (0 < end);
2035 gdb_assert (index < end);
2036
2037 return &bfun->insn[index];
2038 }
2039
2040 /* See btrace.h. */
2041
2042 int
btrace_insn_get_error(const struct btrace_insn_iterator * it)2043 btrace_insn_get_error (const struct btrace_insn_iterator *it)
2044 {
2045 return it->btinfo->functions[it->call_index].errcode;
2046 }
2047
2048 /* See btrace.h. */
2049
2050 unsigned int
btrace_insn_number(const struct btrace_insn_iterator * it)2051 btrace_insn_number (const struct btrace_insn_iterator *it)
2052 {
2053 return it->btinfo->functions[it->call_index].insn_offset + it->insn_index;
2054 }
2055
2056 /* See btrace.h. */
2057
2058 void
btrace_insn_begin(struct btrace_insn_iterator * it,const struct btrace_thread_info * btinfo)2059 btrace_insn_begin (struct btrace_insn_iterator *it,
2060 const struct btrace_thread_info *btinfo)
2061 {
2062 if (btinfo->functions.empty ())
2063 error (_("No trace."));
2064
2065 it->btinfo = btinfo;
2066 it->call_index = 0;
2067 it->insn_index = 0;
2068 }
2069
2070 /* See btrace.h. */
2071
2072 void
btrace_insn_end(struct btrace_insn_iterator * it,const struct btrace_thread_info * btinfo)2073 btrace_insn_end (struct btrace_insn_iterator *it,
2074 const struct btrace_thread_info *btinfo)
2075 {
2076 const struct btrace_function *bfun;
2077 unsigned int length;
2078
2079 if (btinfo->functions.empty ())
2080 error (_("No trace."));
2081
2082 bfun = &btinfo->functions.back ();
2083 length = bfun->insn.size ();
2084
2085 /* The last function may either be a gap or it contains the current
2086 instruction, which is one past the end of the execution trace; ignore
2087 it. */
2088 if (length > 0)
2089 length -= 1;
2090
2091 it->btinfo = btinfo;
2092 it->call_index = bfun->number - 1;
2093 it->insn_index = length;
2094 }
2095
2096 /* See btrace.h. */
2097
2098 unsigned int
btrace_insn_next(struct btrace_insn_iterator * it,unsigned int stride)2099 btrace_insn_next (struct btrace_insn_iterator *it, unsigned int stride)
2100 {
2101 const struct btrace_function *bfun;
2102 unsigned int index, steps;
2103
2104 bfun = &it->btinfo->functions[it->call_index];
2105 steps = 0;
2106 index = it->insn_index;
2107
2108 while (stride != 0)
2109 {
2110 unsigned int end, space, adv;
2111
2112 end = bfun->insn.size ();
2113
2114 /* An empty function segment represents a gap in the trace. We count
2115 it as one instruction. */
2116 if (end == 0)
2117 {
2118 const struct btrace_function *next;
2119
2120 next = ftrace_find_call_by_number (it->btinfo, bfun->number + 1);
2121 if (next == NULL)
2122 break;
2123
2124 stride -= 1;
2125 steps += 1;
2126
2127 bfun = next;
2128 index = 0;
2129
2130 continue;
2131 }
2132
2133 gdb_assert (0 < end);
2134 gdb_assert (index < end);
2135
2136 /* Compute the number of instructions remaining in this segment. */
2137 space = end - index;
2138
2139 /* Advance the iterator as far as possible within this segment. */
2140 adv = std::min (space, stride);
2141 stride -= adv;
2142 index += adv;
2143 steps += adv;
2144
2145 /* Move to the next function if we're at the end of this one. */
2146 if (index == end)
2147 {
2148 const struct btrace_function *next;
2149
2150 next = ftrace_find_call_by_number (it->btinfo, bfun->number + 1);
2151 if (next == NULL)
2152 {
2153 /* We stepped past the last function.
2154
2155 Let's adjust the index to point to the last instruction in
2156 the previous function. */
2157 index -= 1;
2158 steps -= 1;
2159 break;
2160 }
2161
2162 /* We now point to the first instruction in the new function. */
2163 bfun = next;
2164 index = 0;
2165 }
2166
2167 /* We did make progress. */
2168 gdb_assert (adv > 0);
2169 }
2170
2171 /* Update the iterator. */
2172 it->call_index = bfun->number - 1;
2173 it->insn_index = index;
2174
2175 return steps;
2176 }
2177
2178 /* See btrace.h. */
2179
2180 unsigned int
btrace_insn_prev(struct btrace_insn_iterator * it,unsigned int stride)2181 btrace_insn_prev (struct btrace_insn_iterator *it, unsigned int stride)
2182 {
2183 const struct btrace_function *bfun;
2184 unsigned int index, steps;
2185
2186 bfun = &it->btinfo->functions[it->call_index];
2187 steps = 0;
2188 index = it->insn_index;
2189
2190 while (stride != 0)
2191 {
2192 unsigned int adv;
2193
2194 /* Move to the previous function if we're at the start of this one. */
2195 if (index == 0)
2196 {
2197 const struct btrace_function *prev;
2198
2199 prev = ftrace_find_call_by_number (it->btinfo, bfun->number - 1);
2200 if (prev == NULL)
2201 break;
2202
2203 /* We point to one after the last instruction in the new function. */
2204 bfun = prev;
2205 index = bfun->insn.size ();
2206
2207 /* An empty function segment represents a gap in the trace. We count
2208 it as one instruction. */
2209 if (index == 0)
2210 {
2211 stride -= 1;
2212 steps += 1;
2213
2214 continue;
2215 }
2216 }
2217
2218 /* Advance the iterator as far as possible within this segment. */
2219 adv = std::min (index, stride);
2220
2221 stride -= adv;
2222 index -= adv;
2223 steps += adv;
2224
2225 /* We did make progress. */
2226 gdb_assert (adv > 0);
2227 }
2228
2229 /* Update the iterator. */
2230 it->call_index = bfun->number - 1;
2231 it->insn_index = index;
2232
2233 return steps;
2234 }
2235
2236 /* See btrace.h. */
2237
2238 int
btrace_insn_cmp(const struct btrace_insn_iterator * lhs,const struct btrace_insn_iterator * rhs)2239 btrace_insn_cmp (const struct btrace_insn_iterator *lhs,
2240 const struct btrace_insn_iterator *rhs)
2241 {
2242 gdb_assert (lhs->btinfo == rhs->btinfo);
2243
2244 if (lhs->call_index != rhs->call_index)
2245 return lhs->call_index - rhs->call_index;
2246
2247 return lhs->insn_index - rhs->insn_index;
2248 }
2249
2250 /* See btrace.h. */
2251
2252 int
btrace_find_insn_by_number(struct btrace_insn_iterator * it,const struct btrace_thread_info * btinfo,unsigned int number)2253 btrace_find_insn_by_number (struct btrace_insn_iterator *it,
2254 const struct btrace_thread_info *btinfo,
2255 unsigned int number)
2256 {
2257 const struct btrace_function *bfun;
2258 unsigned int upper, lower;
2259
2260 if (btinfo->functions.empty ())
2261 return 0;
2262
2263 lower = 0;
2264 bfun = &btinfo->functions[lower];
2265 if (number < bfun->insn_offset)
2266 return 0;
2267
2268 upper = btinfo->functions.size () - 1;
2269 bfun = &btinfo->functions[upper];
2270 if (number >= bfun->insn_offset + ftrace_call_num_insn (bfun))
2271 return 0;
2272
2273 /* We assume that there are no holes in the numbering. */
2274 for (;;)
2275 {
2276 const unsigned int average = lower + (upper - lower) / 2;
2277
2278 bfun = &btinfo->functions[average];
2279
2280 if (number < bfun->insn_offset)
2281 {
2282 upper = average - 1;
2283 continue;
2284 }
2285
2286 if (number >= bfun->insn_offset + ftrace_call_num_insn (bfun))
2287 {
2288 lower = average + 1;
2289 continue;
2290 }
2291
2292 break;
2293 }
2294
2295 it->btinfo = btinfo;
2296 it->call_index = bfun->number - 1;
2297 it->insn_index = number - bfun->insn_offset;
2298 return 1;
2299 }
2300
2301 /* Returns true if the recording ends with a function segment that
2302 contains only a single (i.e. the current) instruction. */
2303
2304 static bool
btrace_ends_with_single_insn(const struct btrace_thread_info * btinfo)2305 btrace_ends_with_single_insn (const struct btrace_thread_info *btinfo)
2306 {
2307 const btrace_function *bfun;
2308
2309 if (btinfo->functions.empty ())
2310 return false;
2311
2312 bfun = &btinfo->functions.back ();
2313 if (bfun->errcode != 0)
2314 return false;
2315
2316 return ftrace_call_num_insn (bfun) == 1;
2317 }
2318
2319 /* See btrace.h. */
2320
2321 const struct btrace_function *
btrace_call_get(const struct btrace_call_iterator * it)2322 btrace_call_get (const struct btrace_call_iterator *it)
2323 {
2324 if (it->index >= it->btinfo->functions.size ())
2325 return NULL;
2326
2327 return &it->btinfo->functions[it->index];
2328 }
2329
2330 /* See btrace.h. */
2331
2332 unsigned int
btrace_call_number(const struct btrace_call_iterator * it)2333 btrace_call_number (const struct btrace_call_iterator *it)
2334 {
2335 const unsigned int length = it->btinfo->functions.size ();
2336
2337 /* If the last function segment contains only a single instruction (i.e. the
2338 current instruction), skip it. */
2339 if ((it->index == length) && btrace_ends_with_single_insn (it->btinfo))
2340 return length;
2341
2342 return it->index + 1;
2343 }
2344
2345 /* See btrace.h. */
2346
2347 void
btrace_call_begin(struct btrace_call_iterator * it,const struct btrace_thread_info * btinfo)2348 btrace_call_begin (struct btrace_call_iterator *it,
2349 const struct btrace_thread_info *btinfo)
2350 {
2351 if (btinfo->functions.empty ())
2352 error (_("No trace."));
2353
2354 it->btinfo = btinfo;
2355 it->index = 0;
2356 }
2357
2358 /* See btrace.h. */
2359
2360 void
btrace_call_end(struct btrace_call_iterator * it,const struct btrace_thread_info * btinfo)2361 btrace_call_end (struct btrace_call_iterator *it,
2362 const struct btrace_thread_info *btinfo)
2363 {
2364 if (btinfo->functions.empty ())
2365 error (_("No trace."));
2366
2367 it->btinfo = btinfo;
2368 it->index = btinfo->functions.size ();
2369 }
2370
2371 /* See btrace.h. */
2372
2373 unsigned int
btrace_call_next(struct btrace_call_iterator * it,unsigned int stride)2374 btrace_call_next (struct btrace_call_iterator *it, unsigned int stride)
2375 {
2376 const unsigned int length = it->btinfo->functions.size ();
2377
2378 if (it->index + stride < length - 1)
2379 /* Default case: Simply advance the iterator. */
2380 it->index += stride;
2381 else if (it->index + stride == length - 1)
2382 {
2383 /* We land exactly at the last function segment. If it contains only one
2384 instruction (i.e. the current instruction) it is not actually part of
2385 the trace. */
2386 if (btrace_ends_with_single_insn (it->btinfo))
2387 it->index = length;
2388 else
2389 it->index = length - 1;
2390 }
2391 else
2392 {
2393 /* We land past the last function segment and have to adjust the stride.
2394 If the last function segment contains only one instruction (i.e. the
2395 current instruction) it is not actually part of the trace. */
2396 if (btrace_ends_with_single_insn (it->btinfo))
2397 stride = length - it->index - 1;
2398 else
2399 stride = length - it->index;
2400
2401 it->index = length;
2402 }
2403
2404 return stride;
2405 }
2406
2407 /* See btrace.h. */
2408
2409 unsigned int
btrace_call_prev(struct btrace_call_iterator * it,unsigned int stride)2410 btrace_call_prev (struct btrace_call_iterator *it, unsigned int stride)
2411 {
2412 const unsigned int length = it->btinfo->functions.size ();
2413 int steps = 0;
2414
2415 gdb_assert (it->index <= length);
2416
2417 if (stride == 0 || it->index == 0)
2418 return 0;
2419
2420 /* If we are at the end, the first step is a special case. If the last
2421 function segment contains only one instruction (i.e. the current
2422 instruction) it is not actually part of the trace. To be able to step
2423 over this instruction, we need at least one more function segment. */
2424 if ((it->index == length) && (length > 1))
2425 {
2426 if (btrace_ends_with_single_insn (it->btinfo))
2427 it->index = length - 2;
2428 else
2429 it->index = length - 1;
2430
2431 steps = 1;
2432 stride -= 1;
2433 }
2434
2435 stride = std::min (stride, it->index);
2436
2437 it->index -= stride;
2438 return steps + stride;
2439 }
2440
2441 /* See btrace.h. */
2442
2443 int
btrace_call_cmp(const struct btrace_call_iterator * lhs,const struct btrace_call_iterator * rhs)2444 btrace_call_cmp (const struct btrace_call_iterator *lhs,
2445 const struct btrace_call_iterator *rhs)
2446 {
2447 gdb_assert (lhs->btinfo == rhs->btinfo);
2448 return (int) (lhs->index - rhs->index);
2449 }
2450
2451 /* See btrace.h. */
2452
2453 int
btrace_find_call_by_number(struct btrace_call_iterator * it,const struct btrace_thread_info * btinfo,unsigned int number)2454 btrace_find_call_by_number (struct btrace_call_iterator *it,
2455 const struct btrace_thread_info *btinfo,
2456 unsigned int number)
2457 {
2458 const unsigned int length = btinfo->functions.size ();
2459
2460 if ((number == 0) || (number > length))
2461 return 0;
2462
2463 it->btinfo = btinfo;
2464 it->index = number - 1;
2465 return 1;
2466 }
2467
2468 /* See btrace.h. */
2469
2470 void
btrace_set_insn_history(struct btrace_thread_info * btinfo,const struct btrace_insn_iterator * begin,const struct btrace_insn_iterator * end)2471 btrace_set_insn_history (struct btrace_thread_info *btinfo,
2472 const struct btrace_insn_iterator *begin,
2473 const struct btrace_insn_iterator *end)
2474 {
2475 if (btinfo->insn_history == NULL)
2476 btinfo->insn_history = XCNEW (struct btrace_insn_history);
2477
2478 btinfo->insn_history->begin = *begin;
2479 btinfo->insn_history->end = *end;
2480 }
2481
2482 /* See btrace.h. */
2483
2484 void
btrace_set_call_history(struct btrace_thread_info * btinfo,const struct btrace_call_iterator * begin,const struct btrace_call_iterator * end)2485 btrace_set_call_history (struct btrace_thread_info *btinfo,
2486 const struct btrace_call_iterator *begin,
2487 const struct btrace_call_iterator *end)
2488 {
2489 gdb_assert (begin->btinfo == end->btinfo);
2490
2491 if (btinfo->call_history == NULL)
2492 btinfo->call_history = XCNEW (struct btrace_call_history);
2493
2494 btinfo->call_history->begin = *begin;
2495 btinfo->call_history->end = *end;
2496 }
2497
2498 /* See btrace.h. */
2499
2500 int
btrace_is_replaying(struct thread_info * tp)2501 btrace_is_replaying (struct thread_info *tp)
2502 {
2503 return tp->btrace.replay != NULL;
2504 }
2505
2506 /* See btrace.h. */
2507
2508 int
btrace_is_empty(struct thread_info * tp)2509 btrace_is_empty (struct thread_info *tp)
2510 {
2511 struct btrace_insn_iterator begin, end;
2512 struct btrace_thread_info *btinfo;
2513
2514 btinfo = &tp->btrace;
2515
2516 if (btinfo->functions.empty ())
2517 return 1;
2518
2519 btrace_insn_begin (&begin, btinfo);
2520 btrace_insn_end (&end, btinfo);
2521
2522 return btrace_insn_cmp (&begin, &end) == 0;
2523 }
2524
2525 #if defined (HAVE_LIBIPT)
2526
2527 /* Print a single packet. */
2528
2529 static void
pt_print_packet(const struct pt_packet * packet)2530 pt_print_packet (const struct pt_packet *packet)
2531 {
2532 switch (packet->type)
2533 {
2534 default:
2535 gdb_printf (("[??: %x]"), packet->type);
2536 break;
2537
2538 case ppt_psb:
2539 gdb_printf (("psb"));
2540 break;
2541
2542 case ppt_psbend:
2543 gdb_printf (("psbend"));
2544 break;
2545
2546 case ppt_pad:
2547 gdb_printf (("pad"));
2548 break;
2549
2550 case ppt_tip:
2551 gdb_printf (("tip %u: 0x%" PRIx64 ""),
2552 packet->payload.ip.ipc,
2553 packet->payload.ip.ip);
2554 break;
2555
2556 case ppt_tip_pge:
2557 gdb_printf (("tip.pge %u: 0x%" PRIx64 ""),
2558 packet->payload.ip.ipc,
2559 packet->payload.ip.ip);
2560 break;
2561
2562 case ppt_tip_pgd:
2563 gdb_printf (("tip.pgd %u: 0x%" PRIx64 ""),
2564 packet->payload.ip.ipc,
2565 packet->payload.ip.ip);
2566 break;
2567
2568 case ppt_fup:
2569 gdb_printf (("fup %u: 0x%" PRIx64 ""),
2570 packet->payload.ip.ipc,
2571 packet->payload.ip.ip);
2572 break;
2573
2574 case ppt_tnt_8:
2575 gdb_printf (("tnt-8 %u: 0x%" PRIx64 ""),
2576 packet->payload.tnt.bit_size,
2577 packet->payload.tnt.payload);
2578 break;
2579
2580 case ppt_tnt_64:
2581 gdb_printf (("tnt-64 %u: 0x%" PRIx64 ""),
2582 packet->payload.tnt.bit_size,
2583 packet->payload.tnt.payload);
2584 break;
2585
2586 case ppt_pip:
2587 gdb_printf (("pip %" PRIx64 "%s"), packet->payload.pip.cr3,
2588 packet->payload.pip.nr ? (" nr") : (""));
2589 break;
2590
2591 case ppt_tsc:
2592 gdb_printf (("tsc %" PRIx64 ""), packet->payload.tsc.tsc);
2593 break;
2594
2595 case ppt_cbr:
2596 gdb_printf (("cbr %u"), packet->payload.cbr.ratio);
2597 break;
2598
2599 case ppt_mode:
2600 switch (packet->payload.mode.leaf)
2601 {
2602 default:
2603 gdb_printf (("mode %u"), packet->payload.mode.leaf);
2604 break;
2605
2606 case pt_mol_exec:
2607 gdb_printf (("mode.exec%s%s"),
2608 packet->payload.mode.bits.exec.csl
2609 ? (" cs.l") : (""),
2610 packet->payload.mode.bits.exec.csd
2611 ? (" cs.d") : (""));
2612 break;
2613
2614 case pt_mol_tsx:
2615 gdb_printf (("mode.tsx%s%s"),
2616 packet->payload.mode.bits.tsx.intx
2617 ? (" intx") : (""),
2618 packet->payload.mode.bits.tsx.abrt
2619 ? (" abrt") : (""));
2620 break;
2621 }
2622 break;
2623
2624 case ppt_ovf:
2625 gdb_printf (("ovf"));
2626 break;
2627
2628 case ppt_stop:
2629 gdb_printf (("stop"));
2630 break;
2631
2632 case ppt_vmcs:
2633 gdb_printf (("vmcs %" PRIx64 ""), packet->payload.vmcs.base);
2634 break;
2635
2636 case ppt_tma:
2637 gdb_printf (("tma %x %x"), packet->payload.tma.ctc,
2638 packet->payload.tma.fc);
2639 break;
2640
2641 case ppt_mtc:
2642 gdb_printf (("mtc %x"), packet->payload.mtc.ctc);
2643 break;
2644
2645 case ppt_cyc:
2646 gdb_printf (("cyc %" PRIx64 ""), packet->payload.cyc.value);
2647 break;
2648
2649 case ppt_mnt:
2650 gdb_printf (("mnt %" PRIx64 ""), packet->payload.mnt.payload);
2651 break;
2652 }
2653 }
2654
2655 /* Decode packets into MAINT using DECODER. */
2656
2657 static void
btrace_maint_decode_pt(struct btrace_maint_info * maint,struct pt_packet_decoder * decoder)2658 btrace_maint_decode_pt (struct btrace_maint_info *maint,
2659 struct pt_packet_decoder *decoder)
2660 {
2661 int errcode;
2662
2663 if (maint->variant.pt.packets == NULL)
2664 maint->variant.pt.packets = new std::vector<btrace_pt_packet>;
2665
2666 for (;;)
2667 {
2668 struct btrace_pt_packet packet;
2669
2670 errcode = pt_pkt_sync_forward (decoder);
2671 if (errcode < 0)
2672 break;
2673
2674 for (;;)
2675 {
2676 pt_pkt_get_offset (decoder, &packet.offset);
2677
2678 errcode = pt_pkt_next (decoder, &packet.packet,
2679 sizeof(packet.packet));
2680 if (errcode < 0)
2681 break;
2682
2683 if (maint_btrace_pt_skip_pad == 0 || packet.packet.type != ppt_pad)
2684 {
2685 packet.errcode = pt_errcode (errcode);
2686 maint->variant.pt.packets->push_back (packet);
2687 }
2688 }
2689
2690 if (errcode == -pte_eos)
2691 break;
2692
2693 packet.errcode = pt_errcode (errcode);
2694 maint->variant.pt.packets->push_back (packet);
2695
2696 warning (_("Error at trace offset 0x%" PRIx64 ": %s."),
2697 packet.offset, pt_errstr (packet.errcode));
2698 }
2699
2700 if (errcode != -pte_eos)
2701 warning (_("Failed to synchronize onto the Intel Processor Trace "
2702 "stream: %s."), pt_errstr (pt_errcode (errcode)));
2703 }
2704
2705 /* Update the packet history in BTINFO. */
2706
2707 static void
btrace_maint_update_pt_packets(struct btrace_thread_info * btinfo)2708 btrace_maint_update_pt_packets (struct btrace_thread_info *btinfo)
2709 {
2710 struct pt_packet_decoder *decoder;
2711 const struct btrace_cpu *cpu;
2712 struct btrace_data_pt *pt;
2713 struct pt_config config;
2714 int errcode;
2715
2716 pt = &btinfo->data.variant.pt;
2717
2718 /* Nothing to do if there is no trace. */
2719 if (pt->size == 0)
2720 return;
2721
2722 memset (&config, 0, sizeof(config));
2723
2724 config.size = sizeof (config);
2725 config.begin = pt->data;
2726 config.end = pt->data + pt->size;
2727
2728 cpu = record_btrace_get_cpu ();
2729 if (cpu == nullptr)
2730 cpu = &pt->config.cpu;
2731
2732 /* We treat an unknown vendor as 'no errata'. */
2733 if (cpu->vendor != CV_UNKNOWN)
2734 {
2735 config.cpu.vendor = pt_translate_cpu_vendor (cpu->vendor);
2736 config.cpu.family = cpu->family;
2737 config.cpu.model = cpu->model;
2738 config.cpu.stepping = cpu->stepping;
2739
2740 errcode = pt_cpu_errata (&config.errata, &config.cpu);
2741 if (errcode < 0)
2742 error (_("Failed to configure the Intel Processor Trace "
2743 "decoder: %s."), pt_errstr (pt_errcode (errcode)));
2744 }
2745
2746 decoder = pt_pkt_alloc_decoder (&config);
2747 if (decoder == NULL)
2748 error (_("Failed to allocate the Intel Processor Trace decoder."));
2749
2750 try
2751 {
2752 btrace_maint_decode_pt (&btinfo->maint, decoder);
2753 }
2754 catch (const gdb_exception &except)
2755 {
2756 pt_pkt_free_decoder (decoder);
2757
2758 if (except.reason < 0)
2759 throw;
2760 }
2761
2762 pt_pkt_free_decoder (decoder);
2763 }
2764
2765 #endif /* !defined (HAVE_LIBIPT) */
2766
2767 /* Update the packet maintenance information for BTINFO and store the
2768 low and high bounds into BEGIN and END, respectively.
2769 Store the current iterator state into FROM and TO. */
2770
2771 static void
btrace_maint_update_packets(struct btrace_thread_info * btinfo,unsigned int * begin,unsigned int * end,unsigned int * from,unsigned int * to)2772 btrace_maint_update_packets (struct btrace_thread_info *btinfo,
2773 unsigned int *begin, unsigned int *end,
2774 unsigned int *from, unsigned int *to)
2775 {
2776 switch (btinfo->data.format)
2777 {
2778 default:
2779 *begin = 0;
2780 *end = 0;
2781 *from = 0;
2782 *to = 0;
2783 break;
2784
2785 case BTRACE_FORMAT_BTS:
2786 /* Nothing to do - we operate directly on BTINFO->DATA. */
2787 *begin = 0;
2788 *end = btinfo->data.variant.bts.blocks->size ();
2789 *from = btinfo->maint.variant.bts.packet_history.begin;
2790 *to = btinfo->maint.variant.bts.packet_history.end;
2791 break;
2792
2793 #if defined (HAVE_LIBIPT)
2794 case BTRACE_FORMAT_PT:
2795 if (btinfo->maint.variant.pt.packets == nullptr)
2796 btinfo->maint.variant.pt.packets = new std::vector<btrace_pt_packet>;
2797
2798 if (btinfo->maint.variant.pt.packets->empty ())
2799 btrace_maint_update_pt_packets (btinfo);
2800
2801 *begin = 0;
2802 *end = btinfo->maint.variant.pt.packets->size ();
2803 *from = btinfo->maint.variant.pt.packet_history.begin;
2804 *to = btinfo->maint.variant.pt.packet_history.end;
2805 break;
2806 #endif /* defined (HAVE_LIBIPT) */
2807 }
2808 }
2809
2810 /* Print packets in BTINFO from BEGIN (inclusive) until END (exclusive) and
2811 update the current iterator position. */
2812
2813 static void
btrace_maint_print_packets(struct btrace_thread_info * btinfo,unsigned int begin,unsigned int end)2814 btrace_maint_print_packets (struct btrace_thread_info *btinfo,
2815 unsigned int begin, unsigned int end)
2816 {
2817 switch (btinfo->data.format)
2818 {
2819 default:
2820 break;
2821
2822 case BTRACE_FORMAT_BTS:
2823 {
2824 const std::vector<btrace_block> &blocks
2825 = *btinfo->data.variant.bts.blocks;
2826 unsigned int blk;
2827
2828 for (blk = begin; blk < end; ++blk)
2829 {
2830 const btrace_block &block = blocks.at (blk);
2831
2832 gdb_printf ("%u\tbegin: %s, end: %s\n", blk,
2833 core_addr_to_string_nz (block.begin),
2834 core_addr_to_string_nz (block.end));
2835 }
2836
2837 btinfo->maint.variant.bts.packet_history.begin = begin;
2838 btinfo->maint.variant.bts.packet_history.end = end;
2839 }
2840 break;
2841
2842 #if defined (HAVE_LIBIPT)
2843 case BTRACE_FORMAT_PT:
2844 {
2845 const std::vector<btrace_pt_packet> &packets
2846 = *btinfo->maint.variant.pt.packets;
2847 unsigned int pkt;
2848
2849 for (pkt = begin; pkt < end; ++pkt)
2850 {
2851 const struct btrace_pt_packet &packet = packets.at (pkt);
2852
2853 gdb_printf ("%u\t", pkt);
2854 gdb_printf ("0x%" PRIx64 "\t", packet.offset);
2855
2856 if (packet.errcode == pte_ok)
2857 pt_print_packet (&packet.packet);
2858 else
2859 gdb_printf ("[error: %s]", pt_errstr (packet.errcode));
2860
2861 gdb_printf ("\n");
2862 }
2863
2864 btinfo->maint.variant.pt.packet_history.begin = begin;
2865 btinfo->maint.variant.pt.packet_history.end = end;
2866 }
2867 break;
2868 #endif /* defined (HAVE_LIBIPT) */
2869 }
2870 }
2871
2872 /* Read a number from an argument string. */
2873
2874 static unsigned int
get_uint(const char ** arg)2875 get_uint (const char **arg)
2876 {
2877 const char *begin, *pos;
2878 char *end;
2879 unsigned long number;
2880
2881 begin = *arg;
2882 pos = skip_spaces (begin);
2883
2884 if (!isdigit (*pos))
2885 error (_("Expected positive number, got: %s."), pos);
2886
2887 number = strtoul (pos, &end, 10);
2888 if (number > UINT_MAX)
2889 error (_("Number too big."));
2890
2891 *arg += (end - begin);
2892
2893 return (unsigned int) number;
2894 }
2895
2896 /* Read a context size from an argument string. */
2897
2898 static int
get_context_size(const char ** arg)2899 get_context_size (const char **arg)
2900 {
2901 const char *pos = skip_spaces (*arg);
2902
2903 if (!isdigit (*pos))
2904 error (_("Expected positive number, got: %s."), pos);
2905
2906 char *end;
2907 long result = strtol (pos, &end, 10);
2908 *arg = end;
2909 return result;
2910 }
2911
2912 /* Complain about junk at the end of an argument string. */
2913
2914 static void
no_chunk(const char * arg)2915 no_chunk (const char *arg)
2916 {
2917 if (*arg != 0)
2918 error (_("Junk after argument: %s."), arg);
2919 }
2920
2921 /* The "maintenance btrace packet-history" command. */
2922
2923 static void
maint_btrace_packet_history_cmd(const char * arg,int from_tty)2924 maint_btrace_packet_history_cmd (const char *arg, int from_tty)
2925 {
2926 struct btrace_thread_info *btinfo;
2927 unsigned int size, begin, end, from, to;
2928
2929 thread_info *tp = current_inferior ()->find_thread (inferior_ptid);
2930 if (tp == NULL)
2931 error (_("No thread."));
2932
2933 size = 10;
2934 btinfo = &tp->btrace;
2935
2936 btrace_maint_update_packets (btinfo, &begin, &end, &from, &to);
2937 if (begin == end)
2938 {
2939 gdb_printf (_("No trace.\n"));
2940 return;
2941 }
2942
2943 if (arg == NULL || *arg == 0 || strcmp (arg, "+") == 0)
2944 {
2945 from = to;
2946
2947 if (end - from < size)
2948 size = end - from;
2949 to = from + size;
2950 }
2951 else if (strcmp (arg, "-") == 0)
2952 {
2953 to = from;
2954
2955 if (to - begin < size)
2956 size = to - begin;
2957 from = to - size;
2958 }
2959 else
2960 {
2961 from = get_uint (&arg);
2962 if (end <= from)
2963 error (_("'%u' is out of range."), from);
2964
2965 arg = skip_spaces (arg);
2966 if (*arg == ',')
2967 {
2968 arg = skip_spaces (++arg);
2969
2970 if (*arg == '+')
2971 {
2972 arg += 1;
2973 size = get_context_size (&arg);
2974
2975 no_chunk (arg);
2976
2977 if (end - from < size)
2978 size = end - from;
2979 to = from + size;
2980 }
2981 else if (*arg == '-')
2982 {
2983 arg += 1;
2984 size = get_context_size (&arg);
2985
2986 no_chunk (arg);
2987
2988 /* Include the packet given as first argument. */
2989 from += 1;
2990 to = from;
2991
2992 if (to - begin < size)
2993 size = to - begin;
2994 from = to - size;
2995 }
2996 else
2997 {
2998 to = get_uint (&arg);
2999
3000 /* Include the packet at the second argument and silently
3001 truncate the range. */
3002 if (to < end)
3003 to += 1;
3004 else
3005 to = end;
3006
3007 no_chunk (arg);
3008 }
3009 }
3010 else
3011 {
3012 no_chunk (arg);
3013
3014 if (end - from < size)
3015 size = end - from;
3016 to = from + size;
3017 }
3018
3019 dont_repeat ();
3020 }
3021
3022 btrace_maint_print_packets (btinfo, from, to);
3023 }
3024
3025 /* The "maintenance btrace clear-packet-history" command. */
3026
3027 static void
maint_btrace_clear_packet_history_cmd(const char * args,int from_tty)3028 maint_btrace_clear_packet_history_cmd (const char *args, int from_tty)
3029 {
3030 if (args != NULL && *args != 0)
3031 error (_("Invalid argument."));
3032
3033 if (inferior_ptid == null_ptid)
3034 error (_("No thread."));
3035
3036 thread_info *tp = inferior_thread ();
3037 btrace_thread_info *btinfo = &tp->btrace;
3038
3039 /* Must clear the maint data before - it depends on BTINFO->DATA. */
3040 btrace_maint_clear (btinfo);
3041 btinfo->data.clear ();
3042 }
3043
3044 /* The "maintenance btrace clear" command. */
3045
3046 static void
maint_btrace_clear_cmd(const char * args,int from_tty)3047 maint_btrace_clear_cmd (const char *args, int from_tty)
3048 {
3049 if (args != NULL && *args != 0)
3050 error (_("Invalid argument."));
3051
3052 if (inferior_ptid == null_ptid)
3053 error (_("No thread."));
3054
3055 thread_info *tp = inferior_thread ();
3056 btrace_clear (tp);
3057 }
3058
3059 /* The "maintenance info btrace" command. */
3060
3061 static void
maint_info_btrace_cmd(const char * args,int from_tty)3062 maint_info_btrace_cmd (const char *args, int from_tty)
3063 {
3064 struct btrace_thread_info *btinfo;
3065 const struct btrace_config *conf;
3066
3067 if (args != NULL && *args != 0)
3068 error (_("Invalid argument."));
3069
3070 if (inferior_ptid == null_ptid)
3071 error (_("No thread."));
3072
3073 thread_info *tp = inferior_thread ();
3074
3075 btinfo = &tp->btrace;
3076
3077 conf = btrace_conf (btinfo);
3078 if (conf == NULL)
3079 error (_("No btrace configuration."));
3080
3081 gdb_printf (_("Format: %s.\n"),
3082 btrace_format_string (conf->format));
3083
3084 switch (conf->format)
3085 {
3086 default:
3087 break;
3088
3089 case BTRACE_FORMAT_BTS:
3090 gdb_printf (_("Number of packets: %zu.\n"),
3091 btinfo->data.variant.bts.blocks->size ());
3092 break;
3093
3094 #if defined (HAVE_LIBIPT)
3095 case BTRACE_FORMAT_PT:
3096 {
3097 struct pt_version version;
3098
3099 version = pt_library_version ();
3100 gdb_printf (_("Version: %u.%u.%u%s.\n"), version.major,
3101 version.minor, version.build,
3102 version.ext != NULL ? version.ext : "");
3103
3104 btrace_maint_update_pt_packets (btinfo);
3105 gdb_printf (_("Number of packets: %zu.\n"),
3106 ((btinfo->maint.variant.pt.packets == nullptr)
3107 ? 0 : btinfo->maint.variant.pt.packets->size ()));
3108 }
3109 break;
3110 #endif /* defined (HAVE_LIBIPT) */
3111 }
3112 }
3113
3114 /* The "maint show btrace pt skip-pad" show value function. */
3115
3116 static void
show_maint_btrace_pt_skip_pad(struct ui_file * file,int from_tty,struct cmd_list_element * c,const char * value)3117 show_maint_btrace_pt_skip_pad (struct ui_file *file, int from_tty,
3118 struct cmd_list_element *c,
3119 const char *value)
3120 {
3121 gdb_printf (file, _("Skip PAD packets is %s.\n"), value);
3122 }
3123
3124
3125 /* Initialize btrace maintenance commands. */
3126
3127 void _initialize_btrace ();
3128 void
_initialize_btrace()3129 _initialize_btrace ()
3130 {
3131 add_cmd ("btrace", class_maintenance, maint_info_btrace_cmd,
3132 _("Info about branch tracing data."), &maintenanceinfolist);
3133
3134 add_basic_prefix_cmd ("btrace", class_maintenance,
3135 _("Branch tracing maintenance commands."),
3136 &maint_btrace_cmdlist, 0, &maintenancelist);
3137
3138 add_setshow_prefix_cmd ("btrace", class_maintenance,
3139 _("Set branch tracing specific variables."),
3140 _("Show branch tracing specific variables."),
3141 &maint_btrace_set_cmdlist,
3142 &maint_btrace_show_cmdlist,
3143 &maintenance_set_cmdlist,
3144 &maintenance_show_cmdlist);
3145
3146 add_setshow_prefix_cmd ("pt", class_maintenance,
3147 _("Set Intel Processor Trace specific variables."),
3148 _("Show Intel Processor Trace specific variables."),
3149 &maint_btrace_pt_set_cmdlist,
3150 &maint_btrace_pt_show_cmdlist,
3151 &maint_btrace_set_cmdlist,
3152 &maint_btrace_show_cmdlist);
3153
3154 add_setshow_boolean_cmd ("skip-pad", class_maintenance,
3155 &maint_btrace_pt_skip_pad, _("\
3156 Set whether PAD packets should be skipped in the btrace packet history."), _("\
3157 Show whether PAD packets should be skipped in the btrace packet history."),_("\
3158 When enabled, PAD packets are ignored in the btrace packet history."),
3159 NULL, show_maint_btrace_pt_skip_pad,
3160 &maint_btrace_pt_set_cmdlist,
3161 &maint_btrace_pt_show_cmdlist);
3162
3163 add_cmd ("packet-history", class_maintenance, maint_btrace_packet_history_cmd,
3164 _("Print the raw branch tracing data.\n\
3165 With no argument, print ten more packets after the previous ten-line print.\n\
3166 With '-' as argument print ten packets before a previous ten-line print.\n\
3167 One argument specifies the starting packet of a ten-line print.\n\
3168 Two arguments with comma between specify starting and ending packets to \
3169 print.\n\
3170 Preceded with '+'/'-' the second argument specifies the distance from the \
3171 first."),
3172 &maint_btrace_cmdlist);
3173
3174 add_cmd ("clear-packet-history", class_maintenance,
3175 maint_btrace_clear_packet_history_cmd,
3176 _("Clears the branch tracing packet history.\n\
3177 Discards the raw branch tracing data but not the execution history data."),
3178 &maint_btrace_cmdlist);
3179
3180 add_cmd ("clear", class_maintenance, maint_btrace_clear_cmd,
3181 _("Clears the branch tracing data.\n\
3182 Discards the raw branch tracing data and the execution history data.\n\
3183 The next 'record' command will fetch the branch tracing data anew."),
3184 &maint_btrace_cmdlist);
3185
3186 }
3187