Skip to content

Commit eed6a9a

Browse files
author
Alexei Starovoitov
committed
Merge branch 'perf: Add mmap2 build id support'
Jiri Olsa says: ==================== hi, adding the support to have buildid stored in mmap2 event, so we can bypass the final perf record hunt on build ids. This patchset allows perf to record build ID in mmap2 event, and adds perf tooling to store/download binaries to .debug cache based on these build IDs. Note that the build id retrieval code is stolen from bpf code, where it's been used (together with file offsets) to replace IPs in user space stack traces. It's now added under lib directory. v7 changes: - included only missing kernel patches, cc-ed bpf@vger and rebased on bpf-next/master [Alexei] v6 changes: - last 4 patches rebased Arnaldo's perf/core v5 changes: - rebased on latest perf/core - several patches already pulled in - fixed trace+probe_vfs_getname.sh output redirection - fixed changelogs [Arnaldo] - renamed BUILD_ID_SIZE to BUILD_ID_SIZE_MAX [Song] v4 changes: - fixed typo in changelog [Namhyung] - removed force_download bool from struct dso_store_data, because it's not used [Namhyung] v3 changes: - added acks - removed forgotten debug code [Arnaldo] - fixed readlink termination [Ian] - fixed doc for --debuginfod=URLs [Ian] - adopted kernel's memchr_inv function and used it in build_id__is_defined function [Arnaldo] On recording server: - on the recording server we can run record with --buildid-mmap option to store build ids in mmap2 events: # perf record --buildid-mmap ^C[ perf record: Woken up 2 times to write data ] [ perf record: Captured and wrote 0.836 MB perf.data ] - it stores nothing to ~/.debug cache: # find ~/.debug find: ‘/root/.debug’: No such file or directory - and still reports properly: # perf report --stdio ... 99.82% swapper [kernel.kallsyms] [k] native_safe_halt 0.03% swapper [kernel.kallsyms] [k] finish_task_switch 0.02% swapper [kernel.kallsyms] [k] __softirqentry_text_start 0.01% kcompactd0 [kernel.kallsyms] [k] _raw_spin_unlock_irqrestore 0.01% ksoftirqd/6 [kernel.kallsyms] [k] slab_free_freelist_hook 0.01% kworker/17:1H-x [kernel.kallsyms] [k] slab_free_freelist_hook - display used/hit build ids: # perf buildid-list | head -5 5dcec522abf136fcfd3128f47e131f2365834dd7 /proc/kcore 589e403a34f55486bcac848a45e00bcdeedd1ca8 /usr/lib64/libcrypto.so.1.1.1g 94569566d4eac7e9c87ba029d43d4e2158f9527e /usr/lib64/libpthread-2.30.so 559b9702bebe31c6d132c8dc5cc887673d65d5b5 /usr/lib64/libc-2.30.so 40da7abe89f631f60538a17686a7d65c6a02ed31 /usr/lib64/ld-2.30.so - store build id binaries into build id cache: # perf buildid-cache -a perf.data OK 5dcec522abf136fcfd3128f47e131f2365834dd7 /proc/kcore OK 589e403a34f55486bcac848a45e00bcdeedd1ca8 /usr/lib64/libcrypto.so.1.1.1g OK 94569566d4eac7e9c87ba029d43d4e2158f9527e /usr/lib64/libpthread-2.30.so OK 559b9702bebe31c6d132c8dc5cc887673d65d5b5 /usr/lib64/libc-2.30.so OK 40da7abe89f631f60538a17686a7d65c6a02ed31 /usr/lib64/ld-2.30.so OK a674f7a47c78e35a088104647b9640710277b489 /usr/sbin/sshd OK e5cb4ca25f46485bdbc691c3a92e7e111dac3ef2 /usr/bin/bash OK 9bc8589108223c944b452f0819298a0c3cba6215 /usr/bin/find # find ~/.debug | head -5 /root/.debug /root/.debug/proc /root/.debug/proc/kcore /root/.debug/proc/kcore/5dcec522abf136fcfd3128f47e131f2365834dd7 /root/.debug/proc/kcore/5dcec522abf136fcfd3128f47e131f2365834dd7/kallsyms - run debuginfod daemon to provide binaries to another server (below) (the initialization could take some time) # debuginfod -F / On another server: - copy perf.data from 'record' server and run: $ find ~/.debug/ find: ‘/home/jolsa/.debug/’: No such file or directory $ perf buildid-list | head -5 No kallsyms or vmlinux with build-id 5dcec522abf136fcfd3128f47e131f2365834dd7 was found 5dcec522abf136fcfd3128f47e131f2365834dd7 [kernel.kallsyms] 5784f813b727a50cfd3363234aef9fcbab685cc4 /lib/modules/5.10.0-rc2speed+/kernel/fs/xfs/xfs.ko 589e403a34f55486bcac848a45e00bcdeedd1ca8 /usr/lib64/libcrypto.so.1.1.1g 94569566d4eac7e9c87ba029d43d4e2158f9527e /usr/lib64/libpthread-2.30.so 559b9702bebe31c6d132c8dc5cc887673d65d5b5 /usr/lib64/libc-2.30.so - report does not show anything (kernel build id does not match): $ perf report --stdio ... 76.73% swapper [kernel.kallsyms] [k] 0xffffffff81aa8ebe 1.89% find [kernel.kallsyms] [k] 0xffffffff810f2167 0.93% sshd [kernel.kallsyms] [k] 0xffffffff8153380c 0.83% swapper [kernel.kallsyms] [k] 0xffffffff81104b0b 0.71% kworker/u40:2-e [kernel.kallsyms] [k] 0xffffffff810f3850 0.70% kworker/u40:0-e [kernel.kallsyms] [k] 0xffffffff810f3850 0.64% find [kernel.kallsyms] [k] 0xffffffff81a9ba0a 0.63% find [kernel.kallsyms] [k] 0xffffffff81aa93b0 - add build ids does not work, because existing binaries (on another server) have different build ids: $ perf buildid-cache -a perf.data No kallsyms or vmlinux with build-id 5dcec522abf136fcfd3128f47e131f2365834dd7 was found FAIL 5dcec522abf136fcfd3128f47e131f2365834dd7 [kernel.kallsyms] FAIL 5784f813b727a50cfd3363234aef9fcbab685cc4 /lib/modules/5.10.0-rc2speed+/kernel/fs/xfs/xfs.ko FAIL 589e403a34f55486bcac848a45e00bcdeedd1ca8 /usr/lib64/libcrypto.so.1.1.1g FAIL 94569566d4eac7e9c87ba029d43d4e2158f9527e /usr/lib64/libpthread-2.30.so FAIL 559b9702bebe31c6d132c8dc5cc887673d65d5b5 /usr/lib64/libc-2.30.so FAIL 40da7abe89f631f60538a17686a7d65c6a02ed31 /usr/lib64/ld-2.30.so FAIL a674f7a47c78e35a088104647b9640710277b489 /usr/sbin/sshd FAIL e5cb4ca25f46485bdbc691c3a92e7e111dac3ef2 /usr/bin/bash FAIL 9bc8589108223c944b452f0819298a0c3cba6215 /usr/bin/find - add build ids with debuginfod setup pointing to record server: $ perf buildid-cache -a perf.data --debuginfod http://192.168.122.174:8002 No kallsyms or vmlinux with build-id 5dcec522abf136fcfd3128f47e131f2365834dd7 was found OK 5dcec522abf136fcfd3128f47e131f2365834dd7 [kernel.kallsyms] OK 5784f813b727a50cfd3363234aef9fcbab685cc4 /lib/modules/5.10.0-rc2speed+/kernel/fs/xfs/xfs.ko OK 589e403a34f55486bcac848a45e00bcdeedd1ca8 /usr/lib64/libcrypto.so.1.1.1g OK 94569566d4eac7e9c87ba029d43d4e2158f9527e /usr/lib64/libpthread-2.30.so OK 559b9702bebe31c6d132c8dc5cc887673d65d5b5 /usr/lib64/libc-2.30.so OK 40da7abe89f631f60538a17686a7d65c6a02ed31 /usr/lib64/ld-2.30.so OK a674f7a47c78e35a088104647b9640710277b489 /usr/sbin/sshd OK e5cb4ca25f46485bdbc691c3a92e7e111dac3ef2 /usr/bin/bash OK 9bc8589108223c944b452f0819298a0c3cba6215 /usr/bin/find - and report works: $ perf report --stdio ... 76.73% swapper [kernel.kallsyms] [k] native_safe_halt 1.91% find [kernel.kallsyms] [k] queue_work_on 0.93% sshd [kernel.kallsyms] [k] iowrite16 0.83% swapper [kernel.kallsyms] [k] finish_task_switch 0.72% kworker/u40:2-e [kernel.kallsyms] [k] process_one_work 0.70% kworker/u40:0-e [kernel.kallsyms] [k] process_one_work 0.64% find [kernel.kallsyms] [k] syscall_enter_from_user_mode 0.63% find [kernel.kallsyms] [k] _raw_spin_unlock_irqrestore - because we have the data in build id cache: $ find ~/.debug | head -10 .../.debug .../.debug/home .../.debug/home/jolsa .../.debug/home/jolsa/.cache .../.debug/home/jolsa/.cache/debuginfod_client .../.debug/home/jolsa/.cache/debuginfod_client/5dcec522abf136fcfd3128f47e131f2365834dd7 .../.debug/home/jolsa/.cache/debuginfod_client/5dcec522abf136fcfd3128f47e131f2365834dd7/executable .../.debug/home/jolsa/.cache/debuginfod_client/5dcec522abf136fcfd3128f47e131f2365834dd7/executable/5dcec522abf136fcfd3128f47e131f2365834dd7 .../.debug/home/jolsa/.cache/debuginfod_client/5dcec522abf136fcfd3128f47e131f2365834dd7/executable/5dcec522abf136fcfd3128f47e131f2365834dd7/elf .../.debug/home/jolsa/.cache/debuginfod_client/5dcec522abf136fcfd3128f47e131f2365834dd7/executable/5dcec522abf136fcfd3128f47e131f2365834dd7/debug Available also in: git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git perf/build_id thanks, jirka ==================== Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2 parents 7064a73 + 88a16a1 commit eed6a9a

File tree

6 files changed

+232
-149
lines changed

6 files changed

+232
-149
lines changed

include/linux/buildid.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#ifndef _LINUX_BUILDID_H
3+
#define _LINUX_BUILDID_H
4+
5+
#include <linux/mm_types.h>
6+
7+
#define BUILD_ID_SIZE_MAX 20
8+
9+
int build_id_parse(struct vm_area_struct *vma, unsigned char *build_id,
10+
__u32 *size);
11+
12+
#endif

include/uapi/linux/perf_event.h

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,8 @@ struct perf_event_attr {
386386
aux_output : 1, /* generate AUX records instead of events */
387387
cgroup : 1, /* include cgroup events */
388388
text_poke : 1, /* include text poke events */
389-
__reserved_1 : 30;
389+
build_id : 1, /* use build id in mmap2 events */
390+
__reserved_1 : 29;
390391

391392
union {
392393
__u32 wakeup_events; /* wakeup every n events */
@@ -659,6 +660,22 @@ struct perf_event_mmap_page {
659660
__u64 aux_size;
660661
};
661662

663+
/*
664+
* The current state of perf_event_header::misc bits usage:
665+
* ('|' used bit, '-' unused bit)
666+
*
667+
* 012 CDEF
668+
* |||---------||||
669+
*
670+
* Where:
671+
* 0-2 CPUMODE_MASK
672+
*
673+
* C PROC_MAP_PARSE_TIMEOUT
674+
* D MMAP_DATA / COMM_EXEC / FORK_EXEC / SWITCH_OUT
675+
* E MMAP_BUILD_ID / EXACT_IP / SCHED_OUT_PREEMPT
676+
* F (reserved)
677+
*/
678+
662679
#define PERF_RECORD_MISC_CPUMODE_MASK (7 << 0)
663680
#define PERF_RECORD_MISC_CPUMODE_UNKNOWN (0 << 0)
664681
#define PERF_RECORD_MISC_KERNEL (1 << 0)
@@ -690,6 +707,7 @@ struct perf_event_mmap_page {
690707
*
691708
* PERF_RECORD_MISC_EXACT_IP - PERF_RECORD_SAMPLE of precise events
692709
* PERF_RECORD_MISC_SWITCH_OUT_PREEMPT - PERF_RECORD_SWITCH* events
710+
* PERF_RECORD_MISC_MMAP_BUILD_ID - PERF_RECORD_MMAP2 event
693711
*
694712
*
695713
* PERF_RECORD_MISC_EXACT_IP:
@@ -699,9 +717,13 @@ struct perf_event_mmap_page {
699717
*
700718
* PERF_RECORD_MISC_SWITCH_OUT_PREEMPT:
701719
* Indicates that thread was preempted in TASK_RUNNING state.
720+
*
721+
* PERF_RECORD_MISC_MMAP_BUILD_ID:
722+
* Indicates that mmap2 event carries build id data.
702723
*/
703724
#define PERF_RECORD_MISC_EXACT_IP (1 << 14)
704725
#define PERF_RECORD_MISC_SWITCH_OUT_PREEMPT (1 << 14)
726+
#define PERF_RECORD_MISC_MMAP_BUILD_ID (1 << 14)
705727
/*
706728
* Reserve the last bit to indicate some extended misc field
707729
*/
@@ -915,10 +937,20 @@ enum perf_event_type {
915937
* u64 addr;
916938
* u64 len;
917939
* u64 pgoff;
918-
* u32 maj;
919-
* u32 min;
920-
* u64 ino;
921-
* u64 ino_generation;
940+
* union {
941+
* struct {
942+
* u32 maj;
943+
* u32 min;
944+
* u64 ino;
945+
* u64 ino_generation;
946+
* };
947+
* struct {
948+
* u8 build_id_size;
949+
* u8 __reserved_1;
950+
* u16 __reserved_2;
951+
* u8 build_id[20];
952+
* };
953+
* };
922954
* u32 prot, flags;
923955
* char filename[];
924956
* struct sample_id sample_id;

kernel/bpf/stackmap.c

Lines changed: 4 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@
77
#include <linux/kernel.h>
88
#include <linux/stacktrace.h>
99
#include <linux/perf_event.h>
10-
#include <linux/elf.h>
11-
#include <linux/pagemap.h>
1210
#include <linux/irq_work.h>
1311
#include <linux/btf_ids.h>
12+
#include <linux/buildid.h>
1413
#include "percpu_freelist.h"
1514

1615
#define STACK_CREATE_FLAG_MASK \
@@ -143,140 +142,6 @@ static struct bpf_map *stack_map_alloc(union bpf_attr *attr)
143142
return ERR_PTR(err);
144143
}
145144

146-
#define BPF_BUILD_ID 3
147-
/*
148-
* Parse build id from the note segment. This logic can be shared between
149-
* 32-bit and 64-bit system, because Elf32_Nhdr and Elf64_Nhdr are
150-
* identical.
151-
*/
152-
static inline int stack_map_parse_build_id(void *page_addr,
153-
unsigned char *build_id,
154-
void *note_start,
155-
Elf32_Word note_size)
156-
{
157-
Elf32_Word note_offs = 0, new_offs;
158-
159-
/* check for overflow */
160-
if (note_start < page_addr || note_start + note_size < note_start)
161-
return -EINVAL;
162-
163-
/* only supports note that fits in the first page */
164-
if (note_start + note_size > page_addr + PAGE_SIZE)
165-
return -EINVAL;
166-
167-
while (note_offs + sizeof(Elf32_Nhdr) < note_size) {
168-
Elf32_Nhdr *nhdr = (Elf32_Nhdr *)(note_start + note_offs);
169-
170-
if (nhdr->n_type == BPF_BUILD_ID &&
171-
nhdr->n_namesz == sizeof("GNU") &&
172-
nhdr->n_descsz > 0 &&
173-
nhdr->n_descsz <= BPF_BUILD_ID_SIZE) {
174-
memcpy(build_id,
175-
note_start + note_offs +
176-
ALIGN(sizeof("GNU"), 4) + sizeof(Elf32_Nhdr),
177-
nhdr->n_descsz);
178-
memset(build_id + nhdr->n_descsz, 0,
179-
BPF_BUILD_ID_SIZE - nhdr->n_descsz);
180-
return 0;
181-
}
182-
new_offs = note_offs + sizeof(Elf32_Nhdr) +
183-
ALIGN(nhdr->n_namesz, 4) + ALIGN(nhdr->n_descsz, 4);
184-
if (new_offs <= note_offs) /* overflow */
185-
break;
186-
note_offs = new_offs;
187-
}
188-
return -EINVAL;
189-
}
190-
191-
/* Parse build ID from 32-bit ELF */
192-
static int stack_map_get_build_id_32(void *page_addr,
193-
unsigned char *build_id)
194-
{
195-
Elf32_Ehdr *ehdr = (Elf32_Ehdr *)page_addr;
196-
Elf32_Phdr *phdr;
197-
int i;
198-
199-
/* only supports phdr that fits in one page */
200-
if (ehdr->e_phnum >
201-
(PAGE_SIZE - sizeof(Elf32_Ehdr)) / sizeof(Elf32_Phdr))
202-
return -EINVAL;
203-
204-
phdr = (Elf32_Phdr *)(page_addr + sizeof(Elf32_Ehdr));
205-
206-
for (i = 0; i < ehdr->e_phnum; ++i) {
207-
if (phdr[i].p_type == PT_NOTE &&
208-
!stack_map_parse_build_id(page_addr, build_id,
209-
page_addr + phdr[i].p_offset,
210-
phdr[i].p_filesz))
211-
return 0;
212-
}
213-
return -EINVAL;
214-
}
215-
216-
/* Parse build ID from 64-bit ELF */
217-
static int stack_map_get_build_id_64(void *page_addr,
218-
unsigned char *build_id)
219-
{
220-
Elf64_Ehdr *ehdr = (Elf64_Ehdr *)page_addr;
221-
Elf64_Phdr *phdr;
222-
int i;
223-
224-
/* only supports phdr that fits in one page */
225-
if (ehdr->e_phnum >
226-
(PAGE_SIZE - sizeof(Elf64_Ehdr)) / sizeof(Elf64_Phdr))
227-
return -EINVAL;
228-
229-
phdr = (Elf64_Phdr *)(page_addr + sizeof(Elf64_Ehdr));
230-
231-
for (i = 0; i < ehdr->e_phnum; ++i) {
232-
if (phdr[i].p_type == PT_NOTE &&
233-
!stack_map_parse_build_id(page_addr, build_id,
234-
page_addr + phdr[i].p_offset,
235-
phdr[i].p_filesz))
236-
return 0;
237-
}
238-
return -EINVAL;
239-
}
240-
241-
/* Parse build ID of ELF file mapped to vma */
242-
static int stack_map_get_build_id(struct vm_area_struct *vma,
243-
unsigned char *build_id)
244-
{
245-
Elf32_Ehdr *ehdr;
246-
struct page *page;
247-
void *page_addr;
248-
int ret;
249-
250-
/* only works for page backed storage */
251-
if (!vma->vm_file)
252-
return -EINVAL;
253-
254-
page = find_get_page(vma->vm_file->f_mapping, 0);
255-
if (!page)
256-
return -EFAULT; /* page not mapped */
257-
258-
ret = -EINVAL;
259-
page_addr = kmap_atomic(page);
260-
ehdr = (Elf32_Ehdr *)page_addr;
261-
262-
/* compare magic x7f "ELF" */
263-
if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0)
264-
goto out;
265-
266-
/* only support executable file and shared object file */
267-
if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
268-
goto out;
269-
270-
if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
271-
ret = stack_map_get_build_id_32(page_addr, build_id);
272-
else if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
273-
ret = stack_map_get_build_id_64(page_addr, build_id);
274-
out:
275-
kunmap_atomic(page_addr);
276-
put_page(page);
277-
return ret;
278-
}
279-
280145
static void stack_map_get_build_id_offset(struct bpf_stack_build_id *id_offs,
281146
u64 *ips, u32 trace_nr, bool user)
282147
{
@@ -317,18 +182,18 @@ static void stack_map_get_build_id_offset(struct bpf_stack_build_id *id_offs,
317182
for (i = 0; i < trace_nr; i++) {
318183
id_offs[i].status = BPF_STACK_BUILD_ID_IP;
319184
id_offs[i].ip = ips[i];
320-
memset(id_offs[i].build_id, 0, BPF_BUILD_ID_SIZE);
185+
memset(id_offs[i].build_id, 0, BUILD_ID_SIZE_MAX);
321186
}
322187
return;
323188
}
324189

325190
for (i = 0; i < trace_nr; i++) {
326191
vma = find_vma(current->mm, ips[i]);
327-
if (!vma || stack_map_get_build_id(vma, id_offs[i].build_id)) {
192+
if (!vma || build_id_parse(vma, id_offs[i].build_id, NULL)) {
328193
/* per entry fall back to ips */
329194
id_offs[i].status = BPF_STACK_BUILD_ID_IP;
330195
id_offs[i].ip = ips[i];
331-
memset(id_offs[i].build_id, 0, BPF_BUILD_ID_SIZE);
196+
memset(id_offs[i].build_id, 0, BUILD_ID_SIZE_MAX);
332197
continue;
333198
}
334199
id_offs[i].offset = (vma->vm_pgoff << PAGE_SHIFT) + ips[i]

kernel/events/core.c

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
#include <linux/min_heap.h>
5454
#include <linux/highmem.h>
5555
#include <linux/pgtable.h>
56+
#include <linux/buildid.h>
5657

5758
#include "internal.h"
5859

@@ -397,6 +398,7 @@ static atomic_t nr_ksymbol_events __read_mostly;
397398
static atomic_t nr_bpf_events __read_mostly;
398399
static atomic_t nr_cgroup_events __read_mostly;
399400
static atomic_t nr_text_poke_events __read_mostly;
401+
static atomic_t nr_build_id_events __read_mostly;
400402

401403
static LIST_HEAD(pmus);
402404
static DEFINE_MUTEX(pmus_lock);
@@ -4673,6 +4675,8 @@ static void unaccount_event(struct perf_event *event)
46734675
dec = true;
46744676
if (event->attr.mmap || event->attr.mmap_data)
46754677
atomic_dec(&nr_mmap_events);
4678+
if (event->attr.build_id)
4679+
atomic_dec(&nr_build_id_events);
46764680
if (event->attr.comm)
46774681
atomic_dec(&nr_comm_events);
46784682
if (event->attr.namespaces)
@@ -8046,6 +8050,8 @@ struct perf_mmap_event {
80468050
u64 ino;
80478051
u64 ino_generation;
80488052
u32 prot, flags;
8053+
u8 build_id[BUILD_ID_SIZE_MAX];
8054+
u32 build_id_size;
80498055

80508056
struct {
80518057
struct perf_event_header header;
@@ -8077,6 +8083,7 @@ static void perf_event_mmap_output(struct perf_event *event,
80778083
struct perf_sample_data sample;
80788084
int size = mmap_event->event_id.header.size;
80798085
u32 type = mmap_event->event_id.header.type;
8086+
bool use_build_id;
80808087
int ret;
80818088

80828089
if (!perf_event_mmap_match(event, data))
@@ -8101,13 +8108,25 @@ static void perf_event_mmap_output(struct perf_event *event,
81018108
mmap_event->event_id.pid = perf_event_pid(event, current);
81028109
mmap_event->event_id.tid = perf_event_tid(event, current);
81038110

8111+
use_build_id = event->attr.build_id && mmap_event->build_id_size;
8112+
8113+
if (event->attr.mmap2 && use_build_id)
8114+
mmap_event->event_id.header.misc |= PERF_RECORD_MISC_MMAP_BUILD_ID;
8115+
81048116
perf_output_put(&handle, mmap_event->event_id);
81058117

81068118
if (event->attr.mmap2) {
8107-
perf_output_put(&handle, mmap_event->maj);
8108-
perf_output_put(&handle, mmap_event->min);
8109-
perf_output_put(&handle, mmap_event->ino);
8110-
perf_output_put(&handle, mmap_event->ino_generation);
8119+
if (use_build_id) {
8120+
u8 size[4] = { (u8) mmap_event->build_id_size, 0, 0, 0 };
8121+
8122+
__output_copy(&handle, size, 4);
8123+
__output_copy(&handle, mmap_event->build_id, BUILD_ID_SIZE_MAX);
8124+
} else {
8125+
perf_output_put(&handle, mmap_event->maj);
8126+
perf_output_put(&handle, mmap_event->min);
8127+
perf_output_put(&handle, mmap_event->ino);
8128+
perf_output_put(&handle, mmap_event->ino_generation);
8129+
}
81118130
perf_output_put(&handle, mmap_event->prot);
81128131
perf_output_put(&handle, mmap_event->flags);
81138132
}
@@ -8236,6 +8255,9 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event)
82368255

82378256
mmap_event->event_id.header.size = sizeof(mmap_event->event_id) + size;
82388257

8258+
if (atomic_read(&nr_build_id_events))
8259+
build_id_parse(vma, mmap_event->build_id, &mmap_event->build_id_size);
8260+
82398261
perf_iterate_sb(perf_event_mmap_output,
82408262
mmap_event,
82418263
NULL);
@@ -11172,6 +11194,8 @@ static void account_event(struct perf_event *event)
1117211194
inc = true;
1117311195
if (event->attr.mmap || event->attr.mmap_data)
1117411196
atomic_inc(&nr_mmap_events);
11197+
if (event->attr.build_id)
11198+
atomic_inc(&nr_build_id_events);
1117511199
if (event->attr.comm)
1117611200
atomic_inc(&nr_comm_events);
1117711201
if (event->attr.namespaces)

lib/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
3636
flex_proportions.o ratelimit.o show_mem.o \
3737
is_single_threaded.o plist.o decompress.o kobject_uevent.o \
3838
earlycpio.o seq_buf.o siphash.o dec_and_lock.o \
39-
nmi_backtrace.o nodemask.o win_minmax.o memcat_p.o
39+
nmi_backtrace.o nodemask.o win_minmax.o memcat_p.o \
40+
buildid.o
4041

4142
lib-$(CONFIG_PRINTK) += dump_stack.o
4243
lib-$(CONFIG_SMP) += cpumask.o

0 commit comments

Comments
 (0)