int event__process_mmap(event_t *self, struct perf_session *session) { struct thread *thread; struct map *map; dump_printf(" %d/%d: [%#Lx(%#Lx) @ %#Lx]: %s\n", self->mmap.pid, self->mmap.tid, self->mmap.start, self->mmap.len, self->mmap.pgoff, self->mmap.filename); if (self->mmap.pid == 0) { static const char kmmap_prefix[] = "[kernel.kallsyms."; if (self->mmap.filename[0] == '/') { char short_module_name[1024]; char *name = strrchr(self->mmap.filename, '/'), *dot; if (name == NULL) goto out_problem; ++name; /* skip / */ dot = strrchr(name, '.'); if (dot == NULL) goto out_problem; snprintf(short_module_name, sizeof(short_module_name), "[%.*s]", (int)(dot - name), name); strxfrchar(short_module_name, '-', '_'); map = perf_session__new_module_map(session, self->mmap.start, self->mmap.filename); if (map == NULL) goto out_problem; name = strdup(short_module_name); if (name == NULL) goto out_problem; map->dso->short_name = name; map->end = map->start + self->mmap.len; } else if (memcmp(self->mmap.filename, kmmap_prefix, sizeof(kmmap_prefix) - 1) == 0) { const char *symbol_name = (self->mmap.filename + sizeof(kmmap_prefix) - 1); /* * Should be there already, from the build-id table in * the header. */ struct dso *kernel = __dsos__findnew(&dsos__kernel, "[kernel.kallsyms]"); if (kernel == NULL) goto out_problem; kernel->kernel = 1; if (__perf_session__create_kernel_maps(session, kernel) < 0) goto out_problem; session->vmlinux_maps[MAP__FUNCTION]->start = self->mmap.start; session->vmlinux_maps[MAP__FUNCTION]->end = self->mmap.start + self->mmap.len; /* * Be a bit paranoid here, some perf.data file came with * a zero sized synthesized MMAP event for the kernel. */ if (session->vmlinux_maps[MAP__FUNCTION]->end == 0) session->vmlinux_maps[MAP__FUNCTION]->end = ~0UL; perf_session__set_kallsyms_ref_reloc_sym(session, symbol_name, self->mmap.pgoff); } return 0; } thread = perf_session__findnew(session, self->mmap.pid); map = map__new(&self->mmap, MAP__FUNCTION, session->cwd, session->cwdlen); if (thread == NULL || map == NULL) goto out_problem; thread__insert_map(thread, map); return 0; out_problem: dump_printf("problem processing PERF_RECORD_MMAP, skipping event.\n"); return 0; }
static int event__process_kernel_mmap(event_t *self, struct perf_session *session) { struct map *map; char kmmap_prefix[PATH_MAX]; struct machine *machine; enum dso_kernel_type kernel_type; bool is_kernel_mmap; machine = perf_session__findnew_machine(session, self->mmap.pid); if (!machine) { pr_err("Can't find id %d's machine\n", self->mmap.pid); goto out_problem; } machine__mmap_name(machine, kmmap_prefix, sizeof(kmmap_prefix)); if (machine__is_host(machine)) kernel_type = DSO_TYPE_KERNEL; else kernel_type = DSO_TYPE_GUEST_KERNEL; is_kernel_mmap = memcmp(self->mmap.filename, kmmap_prefix, strlen(kmmap_prefix)) == 0; if (self->mmap.filename[0] == '/' || (!is_kernel_mmap && self->mmap.filename[0] == '[')) { char short_module_name[1024]; char *name, *dot; if (self->mmap.filename[0] == '/') { name = strrchr(self->mmap.filename, '/'); if (name == NULL) goto out_problem; ++name; /* skip / */ dot = strrchr(name, '.'); if (dot == NULL) goto out_problem; snprintf(short_module_name, sizeof(short_module_name), "[%.*s]", (int)(dot - name), name); strxfrchar(short_module_name, '-', '_'); } else strcpy(short_module_name, self->mmap.filename); map = machine__new_module(machine, self->mmap.start, self->mmap.filename); if (map == NULL) goto out_problem; name = strdup(short_module_name); if (name == NULL) goto out_problem; map->dso->short_name = name; map->end = map->start + self->mmap.len; } else if (is_kernel_mmap) { const char *symbol_name = (self->mmap.filename + strlen(kmmap_prefix)); /* * Should be there already, from the build-id table in * the header. */ struct dso *kernel = __dsos__findnew(&machine->kernel_dsos, kmmap_prefix); if (kernel == NULL) goto out_problem; kernel->kernel = kernel_type; if (__machine__create_kernel_maps(machine, kernel) < 0) goto out_problem; event_set_kernel_mmap_len(machine->vmlinux_maps, self); perf_session__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, symbol_name, self->mmap.pgoff); if (machine__is_default_guest(machine)) { /* * preload dso of guest kernel and modules */ dso__load(kernel, machine->vmlinux_maps[MAP__FUNCTION], NULL); } } return 0; out_problem: return -1; }