]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/common/linux-btrace.c
convert to_supports_btrace
[thirdparty/binutils-gdb.git] / gdb / common / linux-btrace.c
CommitLineData
7c97f91e
MM
1/* Linux-dependent part of branch trace support for GDB, and GDBserver.
2
ecd75fc8 3 Copyright (C) 2013-2014 Free Software Foundation, Inc.
7c97f91e
MM
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#ifdef GDBSERVER
23#include "server.h"
24#else
25#include "defs.h"
26#endif
27
28#include "linux-btrace.h"
29#include "common-utils.h"
30#include "gdb_assert.h"
31#include "regcache.h"
32#include "gdbthread.h"
be8b1ea6 33#include "gdb_wait.h"
4d157a3d 34#include "i386-cpuid.h"
7c97f91e 35
5b4e221c
MF
36#ifdef HAVE_SYS_SYSCALL_H
37#include <sys/syscall.h>
38#endif
39
40#if HAVE_LINUX_PERF_EVENT_H && defined(SYS_perf_event_open)
7c97f91e
MM
41
42#include <errno.h>
43#include <string.h>
44#include <stdint.h>
45#include <unistd.h>
7c97f91e
MM
46#include <sys/mman.h>
47#include <sys/user.h>
a950d57c
MM
48#include <sys/ptrace.h>
49#include <sys/types.h>
a950d57c 50#include <signal.h>
7c97f91e
MM
51
52/* A branch trace record in perf_event. */
53struct perf_event_bts
54{
55 /* The linear address of the branch source. */
56 uint64_t from;
57
58 /* The linear address of the branch destination. */
59 uint64_t to;
60};
61
62/* A perf_event branch trace sample. */
63struct perf_event_sample
64{
65 /* The perf_event sample header. */
66 struct perf_event_header header;
67
68 /* The perf_event branch tracing payload. */
69 struct perf_event_bts bts;
70};
71
72/* Get the perf_event header. */
73
74static inline volatile struct perf_event_mmap_page *
75perf_event_header (struct btrace_target_info* tinfo)
76{
77 return tinfo->buffer;
78}
79
80/* Get the size of the perf_event mmap buffer. */
81
82static inline size_t
83perf_event_mmap_size (const struct btrace_target_info *tinfo)
84{
85 /* The branch trace buffer is preceded by a configuration page. */
86 return (tinfo->size + 1) * PAGE_SIZE;
87}
88
89/* Get the size of the perf_event buffer. */
90
91static inline size_t
92perf_event_buffer_size (struct btrace_target_info* tinfo)
93{
94 return tinfo->size * PAGE_SIZE;
95}
96
97/* Get the start address of the perf_event buffer. */
98
99static inline const uint8_t *
100perf_event_buffer_begin (struct btrace_target_info* tinfo)
101{
102 return ((const uint8_t *) tinfo->buffer) + PAGE_SIZE;
103}
104
105/* Get the end address of the perf_event buffer. */
106
107static inline const uint8_t *
108perf_event_buffer_end (struct btrace_target_info* tinfo)
109{
110 return perf_event_buffer_begin (tinfo) + perf_event_buffer_size (tinfo);
111}
112
113/* Check whether an address is in the kernel. */
114
115static inline int
116perf_event_is_kernel_addr (const struct btrace_target_info *tinfo,
117 uint64_t addr)
118{
119 uint64_t mask;
120
121 /* If we don't know the size of a pointer, we can't check. Let's assume it's
122 not a kernel address in this case. */
123 if (tinfo->ptr_bits == 0)
124 return 0;
125
126 /* A bit mask for the most significant bit in an address. */
127 mask = (uint64_t) 1 << (tinfo->ptr_bits - 1);
128
129 /* Check whether the most significant bit in the address is set. */
130 return (addr & mask) != 0;
131}
132
133/* Check whether a perf event record should be skipped. */
134
135static inline int
136perf_event_skip_record (const struct btrace_target_info *tinfo,
137 const struct perf_event_bts *bts)
138{
139 /* The hardware may report branches from kernel into user space. Branches
140 from user into kernel space will be suppressed. We filter the former to
141 provide a consistent branch trace excluding kernel. */
142 return perf_event_is_kernel_addr (tinfo, bts->from);
143}
144
145/* Perform a few consistency checks on a perf event sample record. This is
146 meant to catch cases when we get out of sync with the perf event stream. */
147
148static inline int
149perf_event_sample_ok (const struct perf_event_sample *sample)
150{
151 if (sample->header.type != PERF_RECORD_SAMPLE)
152 return 0;
153
154 if (sample->header.size != sizeof (*sample))
155 return 0;
156
157 return 1;
158}
159
160/* Branch trace is collected in a circular buffer [begin; end) as pairs of from
161 and to addresses (plus a header).
162
163 Start points into that buffer at the next sample position.
164 We read the collected samples backwards from start.
165
166 While reading the samples, we convert the information into a list of blocks.
167 For two adjacent samples s1 and s2, we form a block b such that b.begin =
168 s1.to and b.end = s2.from.
169
170 In case the buffer overflows during sampling, one sample may have its lower
171 part at the end and its upper part at the beginning of the buffer. */
172
173static VEC (btrace_block_s) *
174perf_event_read_bts (struct btrace_target_info* tinfo, const uint8_t *begin,
969c39fb 175 const uint8_t *end, const uint8_t *start, size_t size)
7c97f91e
MM
176{
177 VEC (btrace_block_s) *btrace = NULL;
178 struct perf_event_sample sample;
969c39fb 179 size_t read = 0;
7c97f91e
MM
180 struct btrace_block block = { 0, 0 };
181 struct regcache *regcache;
182
183 gdb_assert (begin <= start);
184 gdb_assert (start <= end);
185
186 /* The first block ends at the current pc. */
187#ifdef GDBSERVER
188 regcache = get_thread_regcache (find_thread_ptid (tinfo->ptid), 1);
189#else
190 regcache = get_thread_regcache (tinfo->ptid);
191#endif
192 block.end = regcache_read_pc (regcache);
193
194 /* The buffer may contain a partial record as its last entry (i.e. when the
195 buffer size is not a multiple of the sample size). */
196 read = sizeof (sample) - 1;
197
198 for (; read < size; read += sizeof (sample))
199 {
200 const struct perf_event_sample *psample;
201
202 /* Find the next perf_event sample in a backwards traversal. */
203 start -= sizeof (sample);
204
205 /* If we're still inside the buffer, we're done. */
206 if (begin <= start)
207 psample = (const struct perf_event_sample *) start;
208 else
209 {
210 int missing;
211
212 /* We're to the left of the ring buffer, we will wrap around and
213 reappear at the very right of the ring buffer. */
214
215 missing = (begin - start);
216 start = (end - missing);
217
218 /* If the entire sample is missing, we're done. */
219 if (missing == sizeof (sample))
220 psample = (const struct perf_event_sample *) start;
221 else
222 {
223 uint8_t *stack;
224
225 /* The sample wrapped around. The lower part is at the end and
226 the upper part is at the beginning of the buffer. */
227 stack = (uint8_t *) &sample;
228
229 /* Copy the two parts so we have a contiguous sample. */
230 memcpy (stack, start, missing);
231 memcpy (stack + missing, begin, sizeof (sample) - missing);
232
233 psample = &sample;
234 }
235 }
236
237 if (!perf_event_sample_ok (psample))
238 {
239 warning (_("Branch trace may be incomplete."));
240 break;
241 }
242
243 if (perf_event_skip_record (tinfo, &psample->bts))
244 continue;
245
246 /* We found a valid sample, so we can complete the current block. */
247 block.begin = psample->bts.to;
248
249 VEC_safe_push (btrace_block_s, btrace, &block);
250
251 /* Start the next block. */
252 block.end = psample->bts.from;
253 }
254
969c39fb
MM
255 /* Push the last block (i.e. the first one of inferior execution), as well.
256 We don't know where it ends, but we know where it starts. If we're
257 reading delta trace, we can fill in the start address later on.
258 Otherwise we will prune it. */
259 block.begin = 0;
260 VEC_safe_push (btrace_block_s, btrace, &block);
261
7c97f91e
MM
262 return btrace;
263}
264
a950d57c
MM
265/* Check whether the kernel supports branch tracing. */
266
267static int
268kernel_supports_btrace (void)
269{
270 struct perf_event_attr attr;
271 pid_t child, pid;
272 int status, file;
273
274 errno = 0;
275 child = fork ();
276 switch (child)
277 {
278 case -1:
279 warning (_("test branch tracing: cannot fork: %s."), strerror (errno));
280 return 0;
281
282 case 0:
283 status = ptrace (PTRACE_TRACEME, 0, NULL, NULL);
284 if (status != 0)
285 {
286 warning (_("test branch tracing: cannot PTRACE_TRACEME: %s."),
287 strerror (errno));
288 _exit (1);
289 }
290
291 status = raise (SIGTRAP);
292 if (status != 0)
293 {
294 warning (_("test branch tracing: cannot raise SIGTRAP: %s."),
295 strerror (errno));
296 _exit (1);
297 }
298
299 _exit (1);
300
301 default:
302 pid = waitpid (child, &status, 0);
303 if (pid != child)
304 {
305 warning (_("test branch tracing: bad pid %ld, error: %s."),
306 (long) pid, strerror (errno));
307 return 0;
308 }
309
310 if (!WIFSTOPPED (status))
311 {
312 warning (_("test branch tracing: expected stop. status: %d."),
313 status);
314 return 0;
315 }
316
317 memset (&attr, 0, sizeof (attr));
318
319 attr.type = PERF_TYPE_HARDWARE;
320 attr.config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS;
321 attr.sample_period = 1;
322 attr.sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_ADDR;
323 attr.exclude_kernel = 1;
324 attr.exclude_hv = 1;
325 attr.exclude_idle = 1;
326
327 file = syscall (SYS_perf_event_open, &attr, child, -1, -1, 0);
328 if (file >= 0)
329 close (file);
330
331 kill (child, SIGKILL);
332 ptrace (PTRACE_KILL, child, NULL, NULL);
333
334 pid = waitpid (child, &status, 0);
335 if (pid != child)
336 {
337 warning (_("test branch tracing: bad pid %ld, error: %s."),
338 (long) pid, strerror (errno));
339 if (!WIFSIGNALED (status))
340 warning (_("test branch tracing: expected killed. status: %d."),
341 status);
342 }
343
344 return (file >= 0);
345 }
346}
347
348/* Check whether an Intel cpu supports branch tracing. */
349
350static int
351intel_supports_btrace (void)
352{
5f8e0b8f
MF
353 unsigned int cpuid, model, family;
354
4d157a3d
MF
355 if (!i386_cpuid (1, &cpuid, NULL, NULL, NULL))
356 return 0;
5f8e0b8f
MF
357
358 family = (cpuid >> 8) & 0xf;
359 model = (cpuid >> 4) & 0xf;
360
361 switch (family)
362 {
363 case 0x6:
364 model += (cpuid >> 12) & 0xf0;
365
366 switch (model)
367 {
368 case 0x1a: /* Nehalem */
369 case 0x1f:
370 case 0x1e:
371 case 0x2e:
372 case 0x25: /* Westmere */
373 case 0x2c:
374 case 0x2f:
375 case 0x2a: /* Sandy Bridge */
376 case 0x2d:
377 case 0x3a: /* Ivy Bridge */
378
379 /* AAJ122: LBR, BTM, or BTS records may have incorrect branch
380 "from" information afer an EIST transition, T-states, C1E, or
381 Adaptive Thermal Throttling. */
382 return 0;
383 }
384 }
a950d57c
MM
385
386 return 1;
a950d57c
MM
387}
388
389/* Check whether the cpu supports branch tracing. */
390
391static int
392cpu_supports_btrace (void)
393{
4d157a3d 394 unsigned int ebx, ecx, edx;
a950d57c 395
4d157a3d
MF
396 if (!i386_cpuid (0, NULL, &ebx, &ecx, &edx))
397 return 0;
398
4353c9e6
JK
399 if (ebx == signature_INTEL_ebx && ecx == signature_INTEL_ecx
400 && edx == signature_INTEL_edx)
a950d57c
MM
401 return intel_supports_btrace ();
402
403 /* Don't know about others. Let's assume they do. */
404 return 1;
a950d57c
MM
405}
406
7c97f91e
MM
407/* See linux-btrace.h. */
408
409int
46917d26 410linux_supports_btrace (struct target_ops *ops)
7c97f91e 411{
a950d57c
MM
412 static int cached;
413
414 if (cached == 0)
415 {
416 if (!kernel_supports_btrace ())
417 cached = -1;
418 else if (!cpu_supports_btrace ())
419 cached = -1;
420 else
421 cached = 1;
422 }
423
424 return cached > 0;
7c97f91e
MM
425}
426
427/* See linux-btrace.h. */
428
429struct btrace_target_info *
430linux_enable_btrace (ptid_t ptid)
431{
432 struct btrace_target_info *tinfo;
d0fa7535 433 int pid, pg;
7c97f91e
MM
434
435 tinfo = xzalloc (sizeof (*tinfo));
436 tinfo->ptid = ptid;
437
438 tinfo->attr.size = sizeof (tinfo->attr);
439 tinfo->attr.type = PERF_TYPE_HARDWARE;
440 tinfo->attr.config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS;
441 tinfo->attr.sample_period = 1;
442
443 /* We sample from and to address. */
444 tinfo->attr.sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_ADDR;
445
446 tinfo->attr.exclude_kernel = 1;
447 tinfo->attr.exclude_hv = 1;
448 tinfo->attr.exclude_idle = 1;
449
450 tinfo->ptr_bits = 0;
451
452 pid = ptid_get_lwp (ptid);
453 if (pid == 0)
454 pid = ptid_get_pid (ptid);
455
456 errno = 0;
457 tinfo->file = syscall (SYS_perf_event_open, &tinfo->attr, pid, -1, -1, 0);
458 if (tinfo->file < 0)
459 goto err;
460
d0fa7535
MM
461 /* We try to allocate as much buffer as we can get.
462 We could allow the user to specify the size of the buffer, but then
463 we'd leave this search for the maximum buffer size to him. */
464 for (pg = 4; pg >= 0; --pg)
465 {
466 /* The number of pages we request needs to be a power of two. */
467 tinfo->size = 1 << pg;
468 tinfo->buffer = mmap (NULL, perf_event_mmap_size (tinfo),
469 PROT_READ, MAP_SHARED, tinfo->file, 0);
470 if (tinfo->buffer == MAP_FAILED)
471 continue;
7c97f91e 472
d0fa7535
MM
473 return tinfo;
474 }
7c97f91e 475
d0fa7535 476 /* We were not able to allocate any buffer. */
7c97f91e
MM
477 close (tinfo->file);
478
479 err:
480 xfree (tinfo);
481 return NULL;
482}
483
484/* See linux-btrace.h. */
485
969c39fb 486enum btrace_error
7c97f91e
MM
487linux_disable_btrace (struct btrace_target_info *tinfo)
488{
489 int errcode;
490
491 errno = 0;
492 errcode = munmap (tinfo->buffer, perf_event_mmap_size (tinfo));
493 if (errcode != 0)
969c39fb 494 return BTRACE_ERR_UNKNOWN;
7c97f91e
MM
495
496 close (tinfo->file);
497 xfree (tinfo);
498
969c39fb 499 return BTRACE_ERR_NONE;
7c97f91e
MM
500}
501
502/* Check whether the branch trace has changed. */
503
504static int
505linux_btrace_has_changed (struct btrace_target_info *tinfo)
506{
507 volatile struct perf_event_mmap_page *header = perf_event_header (tinfo);
508
509 return header->data_head != tinfo->data_head;
510}
511
512/* See linux-btrace.h. */
513
969c39fb
MM
514enum btrace_error
515linux_read_btrace (VEC (btrace_block_s) **btrace,
516 struct btrace_target_info *tinfo,
7c97f91e
MM
517 enum btrace_read_type type)
518{
7c97f91e
MM
519 volatile struct perf_event_mmap_page *header;
520 const uint8_t *begin, *end, *start;
969c39fb
MM
521 unsigned long data_head, data_tail, retries = 5;
522 size_t buffer_size, size;
7c97f91e 523
969c39fb
MM
524 /* For delta reads, we return at least the partial last block containing
525 the current PC. */
864089d2 526 if (type == BTRACE_READ_NEW && !linux_btrace_has_changed (tinfo))
969c39fb 527 return BTRACE_ERR_NONE;
7c97f91e
MM
528
529 header = perf_event_header (tinfo);
530 buffer_size = perf_event_buffer_size (tinfo);
969c39fb 531 data_tail = tinfo->data_head;
7c97f91e
MM
532
533 /* We may need to retry reading the trace. See below. */
534 while (retries--)
535 {
536 data_head = header->data_head;
537
ed9edfb5 538 /* Delete any leftover trace from the previous iteration. */
969c39fb 539 VEC_free (btrace_block_s, *btrace);
ed9edfb5 540
969c39fb 541 if (type == BTRACE_READ_DELTA)
7c97f91e 542 {
969c39fb
MM
543 /* Determine the number of bytes to read and check for buffer
544 overflows. */
545
546 /* Check for data head overflows. We might be able to recover from
547 those but they are very unlikely and it's not really worth the
548 effort, I think. */
549 if (data_head < data_tail)
550 return BTRACE_ERR_OVERFLOW;
551
552 /* If the buffer is smaller than the trace delta, we overflowed. */
553 size = data_head - data_tail;
554 if (buffer_size < size)
555 return BTRACE_ERR_OVERFLOW;
556 }
557 else
558 {
559 /* Read the entire buffer. */
560 size = buffer_size;
7c97f91e 561
969c39fb
MM
562 /* Adjust the size if the buffer has not overflowed, yet. */
563 if (data_head < size)
564 size = data_head;
7c97f91e
MM
565 }
566
969c39fb
MM
567 /* Data_head keeps growing; the buffer itself is circular. */
568 begin = perf_event_buffer_begin (tinfo);
569 start = begin + data_head % buffer_size;
570
571 if (data_head <= buffer_size)
572 end = start;
573 else
574 end = perf_event_buffer_end (tinfo);
575
576 *btrace = perf_event_read_bts (tinfo, begin, end, start, size);
577
7c97f91e
MM
578 /* The stopping thread notifies its ptracer before it is scheduled out.
579 On multi-core systems, the debugger might therefore run while the
580 kernel might be writing the last branch trace records.
581
582 Let's check whether the data head moved while we read the trace. */
583 if (data_head == header->data_head)
584 break;
585 }
586
587 tinfo->data_head = data_head;
588
969c39fb
MM
589 /* Prune the incomplete last block (i.e. the first one of inferior execution)
590 if we're not doing a delta read. There is no way of filling in its zeroed
591 BEGIN element. */
592 if (!VEC_empty (btrace_block_s, *btrace) && type != BTRACE_READ_DELTA)
593 VEC_pop (btrace_block_s, *btrace);
594
595 return BTRACE_ERR_NONE;
7c97f91e
MM
596}
597
598#else /* !HAVE_LINUX_PERF_EVENT_H */
599
600/* See linux-btrace.h. */
601
602int
46917d26 603linux_supports_btrace (struct target_ops *ops)
7c97f91e
MM
604{
605 return 0;
606}
607
608/* See linux-btrace.h. */
609
610struct btrace_target_info *
611linux_enable_btrace (ptid_t ptid)
612{
613 return NULL;
614}
615
616/* See linux-btrace.h. */
617
969c39fb 618enum btrace_error
7c97f91e
MM
619linux_disable_btrace (struct btrace_target_info *tinfo)
620{
969c39fb 621 return BTRACE_ERR_NOT_SUPPORTED;
7c97f91e
MM
622}
623
624/* See linux-btrace.h. */
625
969c39fb
MM
626enum btrace_error
627linux_read_btrace (VEC (btrace_block_s) **btrace,
628 struct btrace_target_info *tinfo,
7c97f91e
MM
629 enum btrace_read_type type)
630{
969c39fb 631 return BTRACE_ERR_NOT_SUPPORTED;
7c97f91e
MM
632}
633
634#endif /* !HAVE_LINUX_PERF_EVENT_H */