int event__synthesize_kernel_mmap(event__handler_t process, struct perf_session *session, const char *symbol_name) { size_t size; event_t ev = { .header = { .type = PERF_RECORD_MMAP, .misc = 1, /* kernel uses 0 for user space maps, see kernel/perf_event.c __perf_event_mmap */ }, }; /* * We should get this from /sys/kernel/sections/.text, but till that is * available use this, and after it is use this as a fallback for older * kernels. */ struct process_symbol_args args = { .name = symbol_name, }; if (kallsyms__parse("/proc/kallsyms", &args, find_symbol_cb) <= 0) return -ENOENT; size = snprintf(ev.mmap.filename, sizeof(ev.mmap.filename), "[kernel.kallsyms.%s]", symbol_name) + 1; size = ALIGN(size, sizeof(u64)); ev.mmap.header.size = (sizeof(ev.mmap) - (sizeof(ev.mmap.filename) - size)); ev.mmap.pgoff = args.start; ev.mmap.start = session->vmlinux_maps[MAP__FUNCTION]->start; ev.mmap.len = session->vmlinux_maps[MAP__FUNCTION]->end - ev.mmap.start ; return process(&ev, session); }
int event__synthesize_kernel_mmap(event__handler_t process, struct perf_session *session, struct machine *machine, const char *symbol_name) { size_t size; const char *filename, *mmap_name; char path[PATH_MAX]; char name_buff[PATH_MAX]; struct map *map; event_t ev = { .header = { .type = PERF_RECORD_MMAP, }, }; /* * We should get this from /sys/kernel/sections/.text, but till that is * available use this, and after it is use this as a fallback for older * kernels. */ struct process_symbol_args args = { .name = symbol_name, }; mmap_name = machine__mmap_name(machine, name_buff, sizeof(name_buff)); if (machine__is_host(machine)) { /* * kernel uses PERF_RECORD_MISC_USER for user space maps, * see kernel/perf_event.c __perf_event_mmap */ ev.header.misc = PERF_RECORD_MISC_KERNEL; filename = "/proc/kallsyms"; } else { ev.header.misc = PERF_RECORD_MISC_GUEST_KERNEL; if (machine__is_default_guest(machine)) filename = (char *) symbol_conf.default_guest_kallsyms; else { sprintf(path, "%s/proc/kallsyms", machine->root_dir); filename = path; } } if (kallsyms__parse(filename, &args, find_symbol_cb) <= 0) return -ENOENT; map = machine->vmlinux_maps[MAP__FUNCTION]; size = snprintf(ev.mmap.filename, sizeof(ev.mmap.filename), "%s%s", mmap_name, symbol_name) + 1; size = ALIGN(size, sizeof(u64)); ev.mmap.header.size = (sizeof(ev.mmap) - (sizeof(ev.mmap.filename) - size)); ev.mmap.pgoff = args.start; ev.mmap.start = map->start; ev.mmap.len = map->end - ev.mmap.start; ev.mmap.pid = machine->pid; return process(&ev, session); }
u64 kallsyms__get_function_start(const char *kallsyms_filename, const char *symbol_name) { struct process_symbol_args args = { .name = symbol_name, }; if (kallsyms__parse(kallsyms_filename, &args, find_symbol_cb) <= 0) return 0; return args.start; }
int perf_event__synthesize_kernel_mmap(perf_event__handler_t process, struct perf_session *session, struct machine *machine, const char *symbol_name) { size_t size; const char *filename, *mmap_name; char path[PATH_MAX]; char name_buff[PATH_MAX]; struct map *map; int err; /* * We should get this from /sys/kernel/sections/.text, but till that is * available use this, and after it is use this as a fallback for older * kernels. */ struct process_symbol_args args = { .name = symbol_name, }; union perf_event *event = zalloc((sizeof(event->mmap) + session->id_hdr_size)); if (event == NULL) { pr_debug("Not enough memory synthesizing mmap event " "for kernel modules\n"); return -1; } mmap_name = machine__mmap_name(machine, name_buff, sizeof(name_buff)); if (machine__is_host(machine)) { /* * kernel uses PERF_RECORD_MISC_USER for user space maps, * see kernel/perf_event.c __perf_event_mmap */ event->header.misc = PERF_RECORD_MISC_KERNEL; filename = "/proc/kallsyms"; } else { event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL; if (machine__is_default_guest(machine)) filename = (char *) symbol_conf.default_guest_kallsyms; else { sprintf(path, "%s/proc/kallsyms", machine->root_dir); filename = path; } } if (kallsyms__parse(filename, &args, find_symbol_cb) <= 0) return -ENOENT; map = machine->vmlinux_maps[MAP__FUNCTION]; size = snprintf(event->mmap.filename, sizeof(event->mmap.filename), "%s%s", mmap_name, symbol_name) + 1; size = ALIGN(size, sizeof(u64)); event->mmap.header.type = PERF_RECORD_MMAP; event->mmap.header.size = (sizeof(event->mmap) - (sizeof(event->mmap.filename) - size) + session->id_hdr_size); event->mmap.pgoff = args.start; event->mmap.start = map->start; event->mmap.len = map->end - event->mmap.start; event->mmap.pid = machine->pid; err = process(event, &synth_sample, session); free(event); return err; }