char *dso__build_id_filename(struct dso *self, char *bf, size_t size) { char build_id_hex[BUILD_ID_SIZE * 2 + 1]; const char *home; if (!self->has_build_id) return NULL; build_id__sprintf(self->build_id, sizeof(self->build_id), build_id_hex); home = getenv("HOME"); if (bf == NULL) { if (asprintf(&bf, "%s/%s/.build-id/%.2s/%s", home, DEBUG_CACHE_DIR, build_id_hex, build_id_hex + 2) < 0) return NULL; } else snprintf(bf, size, "%s/%s/.build-id/%.2s/%s", home, DEBUG_CACHE_DIR, build_id_hex, build_id_hex + 2); return bf; }
static int build_id_cache__add_file(const char *filename, const char *debugdir) { char sbuild_id[BUILD_ID_SIZE * 2 + 1]; u8 build_id[BUILD_ID_SIZE]; int err; if (filename__read_build_id(filename, &build_id, sizeof(build_id)) < 0) { pr_debug("Couldn't read a build-id in %s\n", filename); return -1; } build_id__sprintf(build_id, sizeof(build_id), sbuild_id); err = build_id_cache__add_s(sbuild_id, debugdir, filename, false, false); if (verbose) pr_info("Adding %s %s: %s\n", sbuild_id, filename, err ? "FAIL" : "Ok"); return err; }
static int build_id_cache__remove_file(const char *filename) { u8 build_id[BUILD_ID_SIZE]; char sbuild_id[SBUILD_ID_SIZE]; int err; if (filename__read_build_id(filename, &build_id, sizeof(build_id)) < 0) { pr_debug("Couldn't read a build-id in %s\n", filename); return -1; } build_id__sprintf(build_id, sizeof(build_id), sbuild_id); err = build_id_cache__remove_s(sbuild_id); pr_debug("Removing %s %s: %s\n", sbuild_id, filename, err ? "FAIL" : "Ok"); return err; }
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 HAVE_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; } return 0; }
static int build_id_cache__add_file(const char *filename, struct nsinfo *nsi) { char sbuild_id[SBUILD_ID_SIZE]; u8 build_id[BUILD_ID_SIZE]; int err; struct nscookie nsc; nsinfo__mountns_enter(nsi, &nsc); err = filename__read_build_id(filename, &build_id, sizeof(build_id)); nsinfo__mountns_exit(&nsc); if (err < 0) { pr_debug("Couldn't read a build-id in %s\n", filename); return -1; } build_id__sprintf(build_id, sizeof(build_id), sbuild_id); err = build_id_cache__add_s(sbuild_id, filename, nsi, false, false); pr_debug("Adding %s %s: %s\n", sbuild_id, filename, err ? "FAIL" : "Ok"); return err; }
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 build_id_cache__kcore_buildid(const char *proc_dir, char *sbuildid) { char root_dir[PATH_MAX]; char notes[PATH_MAX]; u8 build_id[BUILD_ID_SIZE]; char *p; strlcpy(root_dir, proc_dir, sizeof(root_dir)); p = strrchr(root_dir, '/'); if (!p) return -1; *p = '\0'; scnprintf(notes, sizeof(notes), "%s/sys/kernel/notes", root_dir); if (sysfs__read_build_id(notes, build_id, sizeof(build_id))) return -1; build_id__sprintf(build_id, sizeof(build_id), sbuildid); return 0; }
static int build_id_cache__update_file(const char *filename) { u8 build_id[BUILD_ID_SIZE]; char sbuild_id[BUILD_ID_SIZE * 2 + 1]; int err = 0; if (filename__read_build_id(filename, &build_id, sizeof(build_id)) < 0) { pr_debug("Couldn't read a build-id in %s\n", filename); return -1; } build_id__sprintf(build_id, sizeof(build_id), sbuild_id); if (build_id_cache__cached(sbuild_id)) err = build_id_cache__remove_s(sbuild_id); if (!err) err = build_id_cache__add_s(sbuild_id, filename, false, false); pr_debug("Updating %s %s: %s\n", sbuild_id, filename, err ? "FAIL" : "Ok"); return err; }
int dso__read_binary_type_filename(const struct dso *dso, enum dso_binary_type type, char *root_dir, char *filename, size_t size) { char build_id_hex[BUILD_ID_SIZE * 2 + 1]; int ret = 0; size_t len; switch (type) { case DSO_BINARY_TYPE__DEBUGLINK: { char *debuglink; len = __symbol__join_symfs(filename, size, dso->long_name); debuglink = filename + len; while (debuglink != filename && *debuglink != '/') debuglink--; if (*debuglink == '/') debuglink++; ret = -1; if (!is_regular_file(filename)) break; ret = filename__read_debuglink(filename, debuglink, size - (debuglink - filename)); } break; case DSO_BINARY_TYPE__BUILD_ID_CACHE: /* skip the locally configured cache if a symfs is given */ if (symbol_conf.symfs[0] || (dso__build_id_filename(dso, filename, size) == NULL)) ret = -1; break; case DSO_BINARY_TYPE__FEDORA_DEBUGINFO: len = __symbol__join_symfs(filename, size, "/usr/lib/debug"); snprintf(filename + len, size - len, "%s.debug", dso->long_name); break; case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO: len = __symbol__join_symfs(filename, size, "/usr/lib/debug"); snprintf(filename + len, size - len, "%s", dso->long_name); break; case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO: { const char *last_slash; size_t dir_size; last_slash = dso->long_name + dso->long_name_len; while (last_slash != dso->long_name && *last_slash != '/') last_slash--; len = __symbol__join_symfs(filename, size, ""); dir_size = last_slash - dso->long_name + 2; if (dir_size > (size - len)) { ret = -1; break; } len += scnprintf(filename + len, dir_size, "%s", dso->long_name); len += scnprintf(filename + len , size - len, ".debug%s", last_slash); break; } case DSO_BINARY_TYPE__BUILDID_DEBUGINFO: if (!dso->has_build_id) { ret = -1; break; } build_id__sprintf(dso->build_id, sizeof(dso->build_id), build_id_hex); len = __symbol__join_symfs(filename, size, "/usr/lib/debug/.build-id/"); snprintf(filename + len, size - len, "%.2s/%s.debug", build_id_hex, build_id_hex + 2); break; case DSO_BINARY_TYPE__VMLINUX: case DSO_BINARY_TYPE__GUEST_VMLINUX: case DSO_BINARY_TYPE__SYSTEM_PATH_DSO: __symbol__join_symfs(filename, size, dso->long_name); break; case DSO_BINARY_TYPE__GUEST_KMODULE: case DSO_BINARY_TYPE__GUEST_KMODULE_COMP: path__join3(filename, size, symbol_conf.symfs, root_dir, dso->long_name); break; case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE: case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP: __symbol__join_symfs(filename, size, dso->long_name); break; case DSO_BINARY_TYPE__KCORE: case DSO_BINARY_TYPE__GUEST_KCORE: snprintf(filename, size, "%s", dso->long_name); break; default: case DSO_BINARY_TYPE__KALLSYMS: case DSO_BINARY_TYPE__GUEST_KALLSYMS: case DSO_BINARY_TYPE__JAVA_JIT: case DSO_BINARY_TYPE__NOT_FOUND: ret = -1; break; } return ret; }