static struct dso *dsos__findnew(const char *name) { struct dso *dso = dsos__find(name); int nr; if (dso) return dso; dso = dso__new(name, 0); if (!dso) goto out_delete_dso; nr = dso__load(dso, NULL, verbose); if (nr < 0) { if (verbose) fprintf(stderr, "Failed to open: %s\n", name); goto out_delete_dso; } if (!nr && verbose) { fprintf(stderr, "No symbols found in: %s, maybe install a debug package?\n", name); } dsos__add(dso); return dso; out_delete_dso: dso__delete(dso); return NULL; }
int map__load(struct map *map, symbol_filter_t filter) { const char *name = map->dso->long_name; int nr; if (dso__loaded(map->dso, map->type)) return 0; nr = dso__load(map->dso, map, filter); if (nr < 0) { if (map->dso->has_build_id) { char sbuild_id[BUILD_ID_SIZE * 2 + 1]; build_id__sprintf(map->dso->build_id, sizeof(map->dso->build_id), sbuild_id); pr_warning("%s with build id %s not found", name, sbuild_id); } else pr_warning("Failed to open %s", name); pr_warning(", continuing without symbols\n"); return -1; } else if (nr == 0) { #ifdef LIBELF_SUPPORT const size_t len = strlen(name); const size_t real_len = len - sizeof(DSO__DELETED); if (len > sizeof(DSO__DELETED) && strcmp(name + real_len + 1, DSO__DELETED) == 0) { pr_warning("%.*s was updated (is prelink enabled?). " "Restart the long running apps that use it!\n", (int)real_len, name); } else { pr_warning("no symbols found in %s, maybe install " "a debug package?\n", name); } #endif return -1; } /* * Only applies to the kernel, as its symtabs aren't relative like the * module ones. */ if (map->dso->kernel) map__reloc_vmlinux(map); return 0; }
int map__load(struct map *self, symbol_filter_t filter) { const char *name = self->dso->long_name; int nr; if (dso__loaded(self->dso, self->type)) return 0; nr = dso__load(self->dso, self, filter); if (nr < 0) { if (self->dso->has_build_id) { char sbuild_id[BUILD_ID_SIZE * 2 + 1]; build_id__sprintf(self->dso->build_id, sizeof(self->dso->build_id), sbuild_id); pr_warning("%s with build id %s not found", name, sbuild_id); } else pr_warning("Failed to open %s", name); pr_warning(", continuing without symbols\n"); return -1; } else if (nr == 0) { const size_t len = strlen(name); const size_t real_len = len - sizeof(DSO__DELETED); if (len > sizeof(DSO__DELETED) && strcmp(name + real_len + 1, DSO__DELETED) == 0) { pr_warning("%.*s was updated (is prelink enabled?). " "Restart the long running apps that use it!\n", (int)real_len, name); } else { pr_warning("no symbols found in %s, maybe install " "a debug package?\n", name); } return -1; } if (self->dso->kernel) map__reloc_vmlinux(self); return 0; }
struct symbol *map__find_symbol(struct map *self, u64 addr, symbol_filter_t filter) { if (!dso__loaded(self->dso, self->type)) { int nr = dso__load(self->dso, self, filter); if (nr < 0) { if (self->dso->has_build_id) { char sbuild_id[BUILD_ID_SIZE * 2 + 1]; build_id__sprintf(self->dso->build_id, sizeof(self->dso->build_id), sbuild_id); pr_warning("%s with build id %s not found", self->dso->long_name, sbuild_id); } else pr_warning("Failed to open %s", self->dso->long_name); pr_warning(", continuing without symbols\n"); return NULL; } else if (nr == 0) { const char *name = self->dso->long_name; const size_t len = strlen(name); const size_t real_len = len - sizeof(DSO__DELETED); if (len > sizeof(DSO__DELETED) && strcmp(name + real_len + 1, DSO__DELETED) == 0) { pr_warning("%.*s was updated, restart the long running apps that use it!\n", (int)real_len, name); } else { pr_warning("no symbols found in %s, maybe install a debug package?\n", name); } return NULL; } } return self->dso->find_symbol(self->dso, self->type, addr); }
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; }