1 /* Linux-dependent part of branch trace support for GDB, and GDBserver.
3 Copyright (C) 2013 Free Software Foundation, Inc.
5 Contributed by Intel Corp. <markus.t.metzger@intel.com>
7 This file is part of GDB.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
28 #include "linux-btrace.h"
29 #include "common-utils.h"
30 #include "gdb_assert.h"
32 #include "gdbthread.h"
34 #include "i386-cpuid.h"
36 #if HAVE_LINUX_PERF_EVENT_H
42 #include <sys/syscall.h>
45 #include <sys/ptrace.h>
46 #include <sys/types.h>
49 /* A branch trace record in perf_event. */
52 /* The linear address of the branch source. */
55 /* The linear address of the branch destination. */
59 /* A perf_event branch trace sample. */
60 struct perf_event_sample
62 /* The perf_event sample header. */
63 struct perf_event_header header
;
65 /* The perf_event branch tracing payload. */
66 struct perf_event_bts bts
;
69 /* Get the perf_event header. */
71 static inline volatile struct perf_event_mmap_page
*
72 perf_event_header (struct btrace_target_info
* tinfo
)
77 /* Get the size of the perf_event mmap buffer. */
80 perf_event_mmap_size (const struct btrace_target_info
*tinfo
)
82 /* The branch trace buffer is preceded by a configuration page. */
83 return (tinfo
->size
+ 1) * PAGE_SIZE
;
86 /* Get the size of the perf_event buffer. */
89 perf_event_buffer_size (struct btrace_target_info
* tinfo
)
91 return tinfo
->size
* PAGE_SIZE
;
94 /* Get the start address of the perf_event buffer. */
96 static inline const uint8_t *
97 perf_event_buffer_begin (struct btrace_target_info
* tinfo
)
99 return ((const uint8_t *) tinfo
->buffer
) + PAGE_SIZE
;
102 /* Get the end address of the perf_event buffer. */
104 static inline const uint8_t *
105 perf_event_buffer_end (struct btrace_target_info
* tinfo
)
107 return perf_event_buffer_begin (tinfo
) + perf_event_buffer_size (tinfo
);
110 /* Check whether an address is in the kernel. */
113 perf_event_is_kernel_addr (const struct btrace_target_info
*tinfo
,
118 /* If we don't know the size of a pointer, we can't check. Let's assume it's
119 not a kernel address in this case. */
120 if (tinfo
->ptr_bits
== 0)
123 /* A bit mask for the most significant bit in an address. */
124 mask
= (uint64_t) 1 << (tinfo
->ptr_bits
- 1);
126 /* Check whether the most significant bit in the address is set. */
127 return (addr
& mask
) != 0;
130 /* Check whether a perf event record should be skipped. */
133 perf_event_skip_record (const struct btrace_target_info
*tinfo
,
134 const struct perf_event_bts
*bts
)
136 /* The hardware may report branches from kernel into user space. Branches
137 from user into kernel space will be suppressed. We filter the former to
138 provide a consistent branch trace excluding kernel. */
139 return perf_event_is_kernel_addr (tinfo
, bts
->from
);
142 /* Perform a few consistency checks on a perf event sample record. This is
143 meant to catch cases when we get out of sync with the perf event stream. */
146 perf_event_sample_ok (const struct perf_event_sample
*sample
)
148 if (sample
->header
.type
!= PERF_RECORD_SAMPLE
)
151 if (sample
->header
.size
!= sizeof (*sample
))
157 /* Branch trace is collected in a circular buffer [begin; end) as pairs of from
158 and to addresses (plus a header).
160 Start points into that buffer at the next sample position.
161 We read the collected samples backwards from start.
163 While reading the samples, we convert the information into a list of blocks.
164 For two adjacent samples s1 and s2, we form a block b such that b.begin =
165 s1.to and b.end = s2.from.
167 In case the buffer overflows during sampling, one sample may have its lower
168 part at the end and its upper part at the beginning of the buffer. */
170 static VEC (btrace_block_s
) *
171 perf_event_read_bts (struct btrace_target_info
* tinfo
, const uint8_t *begin
,
172 const uint8_t *end
, const uint8_t *start
)
174 VEC (btrace_block_s
) *btrace
= NULL
;
175 struct perf_event_sample sample
;
176 size_t read
= 0, size
= (end
- begin
);
177 struct btrace_block block
= { 0, 0 };
178 struct regcache
*regcache
;
180 gdb_assert (begin
<= start
);
181 gdb_assert (start
<= end
);
183 /* The first block ends at the current pc. */
185 regcache
= get_thread_regcache (find_thread_ptid (tinfo
->ptid
), 1);
187 regcache
= get_thread_regcache (tinfo
->ptid
);
189 block
.end
= regcache_read_pc (regcache
);
191 /* The buffer may contain a partial record as its last entry (i.e. when the
192 buffer size is not a multiple of the sample size). */
193 read
= sizeof (sample
) - 1;
195 for (; read
< size
; read
+= sizeof (sample
))
197 const struct perf_event_sample
*psample
;
199 /* Find the next perf_event sample in a backwards traversal. */
200 start
-= sizeof (sample
);
202 /* If we're still inside the buffer, we're done. */
204 psample
= (const struct perf_event_sample
*) start
;
209 /* We're to the left of the ring buffer, we will wrap around and
210 reappear at the very right of the ring buffer. */
212 missing
= (begin
- start
);
213 start
= (end
- missing
);
215 /* If the entire sample is missing, we're done. */
216 if (missing
== sizeof (sample
))
217 psample
= (const struct perf_event_sample
*) start
;
222 /* The sample wrapped around. The lower part is at the end and
223 the upper part is at the beginning of the buffer. */
224 stack
= (uint8_t *) &sample
;
226 /* Copy the two parts so we have a contiguous sample. */
227 memcpy (stack
, start
, missing
);
228 memcpy (stack
+ missing
, begin
, sizeof (sample
) - missing
);
234 if (!perf_event_sample_ok (psample
))
236 warning (_("Branch trace may be incomplete."));
240 if (perf_event_skip_record (tinfo
, &psample
->bts
))
243 /* We found a valid sample, so we can complete the current block. */
244 block
.begin
= psample
->bts
.to
;
246 VEC_safe_push (btrace_block_s
, btrace
, &block
);
248 /* Start the next block. */
249 block
.end
= psample
->bts
.from
;
255 /* Check whether the kernel supports branch tracing. */
258 kernel_supports_btrace (void)
260 struct perf_event_attr attr
;
269 warning (_("test branch tracing: cannot fork: %s."), strerror (errno
));
273 status
= ptrace (PTRACE_TRACEME
, 0, NULL
, NULL
);
276 warning (_("test branch tracing: cannot PTRACE_TRACEME: %s."),
281 status
= raise (SIGTRAP
);
284 warning (_("test branch tracing: cannot raise SIGTRAP: %s."),
292 pid
= waitpid (child
, &status
, 0);
295 warning (_("test branch tracing: bad pid %ld, error: %s."),
296 (long) pid
, strerror (errno
));
300 if (!WIFSTOPPED (status
))
302 warning (_("test branch tracing: expected stop. status: %d."),
307 memset (&attr
, 0, sizeof (attr
));
309 attr
.type
= PERF_TYPE_HARDWARE
;
310 attr
.config
= PERF_COUNT_HW_BRANCH_INSTRUCTIONS
;
311 attr
.sample_period
= 1;
312 attr
.sample_type
= PERF_SAMPLE_IP
| PERF_SAMPLE_ADDR
;
313 attr
.exclude_kernel
= 1;
315 attr
.exclude_idle
= 1;
317 file
= syscall (SYS_perf_event_open
, &attr
, child
, -1, -1, 0);
321 kill (child
, SIGKILL
);
322 ptrace (PTRACE_KILL
, child
, NULL
, NULL
);
324 pid
= waitpid (child
, &status
, 0);
327 warning (_("test branch tracing: bad pid %ld, error: %s."),
328 (long) pid
, strerror (errno
));
329 if (!WIFSIGNALED (status
))
330 warning (_("test branch tracing: expected killed. status: %d."),
338 /* Check whether an Intel cpu supports branch tracing. */
341 intel_supports_btrace (void)
343 unsigned int cpuid
, model
, family
;
345 if (!i386_cpuid (1, &cpuid
, NULL
, NULL
, NULL
))
348 family
= (cpuid
>> 8) & 0xf;
349 model
= (cpuid
>> 4) & 0xf;
354 model
+= (cpuid
>> 12) & 0xf0;
358 case 0x1a: /* Nehalem */
362 case 0x25: /* Westmere */
365 case 0x2a: /* Sandy Bridge */
367 case 0x3a: /* Ivy Bridge */
369 /* AAJ122: LBR, BTM, or BTS records may have incorrect branch
370 "from" information afer an EIST transition, T-states, C1E, or
371 Adaptive Thermal Throttling. */
379 /* Check whether the cpu supports branch tracing. */
382 cpu_supports_btrace (void)
384 unsigned int ebx
, ecx
, edx
;
386 if (!i386_cpuid (0, NULL
, &ebx
, &ecx
, &edx
))
389 if (ebx
== signature_INTEL_ebx
&& ecx
== signature_INTEL_ecx
390 && edx
== signature_INTEL_edx
)
391 return intel_supports_btrace ();
393 /* Don't know about others. Let's assume they do. */
397 /* See linux-btrace.h. */
400 linux_supports_btrace (void)
406 if (!kernel_supports_btrace ())
408 else if (!cpu_supports_btrace ())
417 /* See linux-btrace.h. */
419 struct btrace_target_info
*
420 linux_enable_btrace (ptid_t ptid
)
422 struct btrace_target_info
*tinfo
;
425 tinfo
= xzalloc (sizeof (*tinfo
));
428 tinfo
->attr
.size
= sizeof (tinfo
->attr
);
429 tinfo
->attr
.type
= PERF_TYPE_HARDWARE
;
430 tinfo
->attr
.config
= PERF_COUNT_HW_BRANCH_INSTRUCTIONS
;
431 tinfo
->attr
.sample_period
= 1;
433 /* We sample from and to address. */
434 tinfo
->attr
.sample_type
= PERF_SAMPLE_IP
| PERF_SAMPLE_ADDR
;
436 tinfo
->attr
.exclude_kernel
= 1;
437 tinfo
->attr
.exclude_hv
= 1;
438 tinfo
->attr
.exclude_idle
= 1;
442 pid
= ptid_get_lwp (ptid
);
444 pid
= ptid_get_pid (ptid
);
447 tinfo
->file
= syscall (SYS_perf_event_open
, &tinfo
->attr
, pid
, -1, -1, 0);
451 /* We hard-code the trace buffer size.
452 At some later time, we should make this configurable. */
454 tinfo
->buffer
= mmap (NULL
, perf_event_mmap_size (tinfo
),
455 PROT_READ
, MAP_SHARED
, tinfo
->file
, 0);
456 if (tinfo
->buffer
== MAP_FAILED
)
469 /* See linux-btrace.h. */
472 linux_disable_btrace (struct btrace_target_info
*tinfo
)
477 errcode
= munmap (tinfo
->buffer
, perf_event_mmap_size (tinfo
));
487 /* Check whether the branch trace has changed. */
490 linux_btrace_has_changed (struct btrace_target_info
*tinfo
)
492 volatile struct perf_event_mmap_page
*header
= perf_event_header (tinfo
);
494 return header
->data_head
!= tinfo
->data_head
;
497 /* See linux-btrace.h. */
499 VEC (btrace_block_s
) *
500 linux_read_btrace (struct btrace_target_info
*tinfo
,
501 enum btrace_read_type type
)
503 VEC (btrace_block_s
) *btrace
= NULL
;
504 volatile struct perf_event_mmap_page
*header
;
505 const uint8_t *begin
, *end
, *start
;
506 unsigned long data_head
, retries
= 5;
509 if (type
== btrace_read_new
&& !linux_btrace_has_changed (tinfo
))
512 header
= perf_event_header (tinfo
);
513 buffer_size
= perf_event_buffer_size (tinfo
);
515 /* We may need to retry reading the trace. See below. */
518 data_head
= header
->data_head
;
520 /* If there's new trace, let's read it. */
521 if (data_head
!= tinfo
->data_head
)
523 /* Data_head keeps growing; the buffer itself is circular. */
524 begin
= perf_event_buffer_begin (tinfo
);
525 start
= begin
+ data_head
% buffer_size
;
527 if (data_head
<= buffer_size
)
530 end
= perf_event_buffer_end (tinfo
);
532 btrace
= perf_event_read_bts (tinfo
, begin
, end
, start
);
535 /* The stopping thread notifies its ptracer before it is scheduled out.
536 On multi-core systems, the debugger might therefore run while the
537 kernel might be writing the last branch trace records.
539 Let's check whether the data head moved while we read the trace. */
540 if (data_head
== header
->data_head
)
544 tinfo
->data_head
= data_head
;
549 #else /* !HAVE_LINUX_PERF_EVENT_H */
551 /* See linux-btrace.h. */
554 linux_supports_btrace (void)
559 /* See linux-btrace.h. */
561 struct btrace_target_info
*
562 linux_enable_btrace (ptid_t ptid
)
567 /* See linux-btrace.h. */
570 linux_disable_btrace (struct btrace_target_info
*tinfo
)
575 /* See linux-btrace.h. */
577 VEC (btrace_block_s
) *
578 linux_read_btrace (struct btrace_target_info
*tinfo
,
579 enum btrace_read_type type
)
584 #endif /* !HAVE_LINUX_PERF_EVENT_H */