struct map *map__new(struct list_head *dsos__list, u64 start, u64 len, u64 pgoff, u32 pid, u32 d_maj, u32 d_min, u64 ino, u64 ino_gen, char *filename, enum map_type type) { struct map *map = malloc(sizeof(*map)); if (map != NULL) { char newfilename[PATH_MAX]; struct dso *dso; int anon, no_dso, vdso; anon = is_anon_memory(filename); vdso = is_vdso_map(filename); no_dso = is_no_dso_memory(filename); map->maj = d_maj; map->min = d_min; map->ino = ino; map->ino_generation = ino_gen; if ((anon || no_dso) && type == MAP__FUNCTION) { snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", pid); filename = newfilename; } if (vdso) { pgoff = 0; dso = vdso__dso_findnew(dsos__list); } else dso = __dsos__findnew(dsos__list, filename); if (dso == NULL) goto out_delete; map__init(map, type, start, start + len, pgoff, dso); if (anon || no_dso) { map->map_ip = map->unmap_ip = identity__map_ip; /* * Set memory without DSO as loaded. All map__find_* * functions still return NULL, and we avoid the * unnecessary map__load warning. */ if (type != MAP__FUNCTION) dso__set_loaded(dso, map->type); } } return map; out_delete: free(map); return NULL; }
struct map *map__new(struct list_head *dsos__list, u64 start, u64 len, u64 pgoff, u32 pid, char *filename, enum map_type type) { struct map *self = malloc(sizeof(*self)); if (self != NULL) { char newfilename[PATH_MAX]; struct dso *dso; int anon, no_dso; anon = is_anon_memory(filename); no_dso = is_no_dso_memory(filename); if (anon) { snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", pid); filename = newfilename; } dso = __dsos__findnew(dsos__list, filename); if (dso == NULL) goto out_delete; map__init(self, type, start, start + len, pgoff, dso); if (anon || no_dso) { self->map_ip = self->unmap_ip = identity__map_ip; /* * Set memory without DSO as loaded. All map__find_* * functions still return NULL, and we avoid the * unnecessary map__load warning. */ if (no_dso) dso__set_loaded(dso, self->type); } } return self; out_delete: free(self); return NULL; }
struct map *map__new(struct list_head *dsos__list, u64 start, u64 len, u64 pgoff, u32 pid, char *filename, enum map_type type) { struct map *self = malloc(sizeof(*self)); if (self != NULL) { char newfilename[PATH_MAX]; struct dso *dso; int anon; anon = is_anon_memory(filename); if (anon) { snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", pid); filename = newfilename; } dso = __dsos__findnew(dsos__list, filename); if (dso == NULL) goto out_delete; map__init(self, type, start, start + len, pgoff, dso); if (anon) { set_identity: self->map_ip = self->unmap_ip = identity__map_ip; } else if (strcmp(filename, "[vdso]") == 0) { dso__set_loaded(dso, self->type); goto set_identity; } } return self; out_delete: free(self); return NULL; }
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; }