^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include <asm/bug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/zalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <sys/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <sys/resource.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <sys/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <sys/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <bpf/libbpf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "bpf-event.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "compress.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "env.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "namespaces.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "path.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "map.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "symbol.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "srcline.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "dso.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "dsos.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "machine.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "auxtrace.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "util.h" /* O_CLOEXEC for older systems */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "string2.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "vdso.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static const char * const debuglink_paths[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) "%.0s%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) "%s/%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) "%s/.debug/%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) "/usr/lib/debug%s/%s"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) char dso__symtab_origin(const struct dso *dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static const char origin[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) [DSO_BINARY_TYPE__KALLSYMS] = 'k',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) [DSO_BINARY_TYPE__VMLINUX] = 'v',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) [DSO_BINARY_TYPE__JAVA_JIT] = 'j',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) [DSO_BINARY_TYPE__DEBUGLINK] = 'l',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) [DSO_BINARY_TYPE__BUILD_ID_CACHE] = 'B',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) [DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO] = 'D',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) [DSO_BINARY_TYPE__FEDORA_DEBUGINFO] = 'f',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) [DSO_BINARY_TYPE__UBUNTU_DEBUGINFO] = 'u',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) [DSO_BINARY_TYPE__MIXEDUP_UBUNTU_DEBUGINFO] = 'x',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) [DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO] = 'o',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) [DSO_BINARY_TYPE__BUILDID_DEBUGINFO] = 'b',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) [DSO_BINARY_TYPE__SYSTEM_PATH_DSO] = 'd',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) [DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE] = 'K',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) [DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP] = 'm',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) [DSO_BINARY_TYPE__GUEST_KALLSYMS] = 'g',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) [DSO_BINARY_TYPE__GUEST_KMODULE] = 'G',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) [DSO_BINARY_TYPE__GUEST_KMODULE_COMP] = 'M',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) [DSO_BINARY_TYPE__GUEST_VMLINUX] = 'V',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (dso == NULL || dso->symtab_type == DSO_BINARY_TYPE__NOT_FOUND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return '!';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return origin[dso->symtab_type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) int dso__read_binary_type_filename(const struct dso *dso,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) enum dso_binary_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) char *root_dir, char *filename, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) char build_id_hex[SBUILD_ID_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) case DSO_BINARY_TYPE__DEBUGLINK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) const char *last_slash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) char dso_dir[PATH_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) char symfile[PATH_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) len = __symbol__join_symfs(filename, size, dso->long_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) last_slash = filename + len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) while (last_slash != filename && *last_slash != '/')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) last_slash--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) strncpy(dso_dir, filename, last_slash - filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) dso_dir[last_slash-filename] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (!is_regular_file(filename)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) ret = filename__read_debuglink(filename, symfile, PATH_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /* Check predefined locations where debug file might reside */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) for (i = 0; i < ARRAY_SIZE(debuglink_paths); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) snprintf(filename, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) debuglink_paths[i], dso_dir, symfile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (is_regular_file(filename)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) case DSO_BINARY_TYPE__BUILD_ID_CACHE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (dso__build_id_filename(dso, filename, size, false) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) case DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (dso__build_id_filename(dso, filename, size, true) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) case DSO_BINARY_TYPE__FEDORA_DEBUGINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) len = __symbol__join_symfs(filename, size, "/usr/lib/debug");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) snprintf(filename + len, size - len, "%s.debug", dso->long_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) len = __symbol__join_symfs(filename, size, "/usr/lib/debug");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) snprintf(filename + len, size - len, "%s", dso->long_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) case DSO_BINARY_TYPE__MIXEDUP_UBUNTU_DEBUGINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * Ubuntu can mixup /usr/lib with /lib, putting debuginfo in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * /usr/lib/debug/lib when it is expected to be in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * /usr/lib/debug/usr/lib
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (strlen(dso->long_name) < 9 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) strncmp(dso->long_name, "/usr/lib/", 9)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) len = __symbol__join_symfs(filename, size, "/usr/lib/debug");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) snprintf(filename + len, size - len, "%s", dso->long_name + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) const char *last_slash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) size_t dir_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) last_slash = dso->long_name + dso->long_name_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) while (last_slash != dso->long_name && *last_slash != '/')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) last_slash--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) len = __symbol__join_symfs(filename, size, "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) dir_size = last_slash - dso->long_name + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (dir_size > (size - len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) len += scnprintf(filename + len, dir_size, "%s", dso->long_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) len += scnprintf(filename + len , size - len, ".debug%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) last_slash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) case DSO_BINARY_TYPE__BUILDID_DEBUGINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (!dso->has_build_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) build_id__sprintf(&dso->bid, build_id_hex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) len = __symbol__join_symfs(filename, size, "/usr/lib/debug/.build-id/");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) snprintf(filename + len, size - len, "%.2s/%s.debug",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) build_id_hex, build_id_hex + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) case DSO_BINARY_TYPE__VMLINUX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) case DSO_BINARY_TYPE__GUEST_VMLINUX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) case DSO_BINARY_TYPE__SYSTEM_PATH_DSO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) __symbol__join_symfs(filename, size, dso->long_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) case DSO_BINARY_TYPE__GUEST_KMODULE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) case DSO_BINARY_TYPE__GUEST_KMODULE_COMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) path__join3(filename, size, symbol_conf.symfs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) root_dir, dso->long_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) __symbol__join_symfs(filename, size, dso->long_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) case DSO_BINARY_TYPE__KCORE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) case DSO_BINARY_TYPE__GUEST_KCORE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) snprintf(filename, size, "%s", dso->long_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) case DSO_BINARY_TYPE__KALLSYMS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) case DSO_BINARY_TYPE__GUEST_KALLSYMS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) case DSO_BINARY_TYPE__JAVA_JIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) case DSO_BINARY_TYPE__BPF_PROG_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) case DSO_BINARY_TYPE__BPF_IMAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) case DSO_BINARY_TYPE__OOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) case DSO_BINARY_TYPE__NOT_FOUND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) COMP_ID__NONE = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static const struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) const char *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) int (*decompress)(const char *input, int output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) bool (*is_compressed)(const char *input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) } compressions[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) [COMP_ID__NONE] = { .fmt = NULL, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) #ifdef HAVE_ZLIB_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) { "gz", gzip_decompress_to_file, gzip_is_compressed },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) #ifdef HAVE_LZMA_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) { "xz", lzma_decompress_to_file, lzma_is_compressed },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) { NULL, NULL, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static int is_supported_compression(const char *ext)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) unsigned i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) for (i = 1; compressions[i].fmt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (!strcmp(ext, compressions[i].fmt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return COMP_ID__NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) bool is_kernel_module(const char *pathname, int cpumode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct kmod_path m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) int mode = cpumode & PERF_RECORD_MISC_CPUMODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) WARN_ONCE(mode != cpumode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) "Internal error: passing unmasked cpumode (%x) to is_kernel_module",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) cpumode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) case PERF_RECORD_MISC_USER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) case PERF_RECORD_MISC_HYPERVISOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) case PERF_RECORD_MISC_GUEST_USER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /* Treat PERF_RECORD_MISC_CPUMODE_UNKNOWN as kernel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (kmod_path__parse(&m, pathname)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) pr_err("Failed to check whether %s is a kernel module or not. Assume it is.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) pathname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return m.kmod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) bool dso__needs_decompress(struct dso *dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static int decompress_kmodule(struct dso *dso, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) char *pathname, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) char tmpbuf[] = KMOD_DECOMP_NAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) int fd = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (!dso__needs_decompress(dso))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (dso->comp == COMP_ID__NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * We have proper compression id for DSO and yet the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * behind the 'name' can still be plain uncompressed object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * The reason is behind the logic we open the DSO object files,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * when we try all possible 'debug' objects until we find the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * data. So even if the DSO is represented by 'krava.xz' module,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) * we can end up here opening ~/.debug/....23432432/debug' file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) * which is not compressed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * To keep this transparent, we detect this and return the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * descriptor to the uncompressed file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (!compressions[dso->comp].is_compressed(name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return open(name, O_RDONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) fd = mkstemp(tmpbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (fd < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) dso->load_errno = errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (compressions[dso->comp].decompress(name, fd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) dso->load_errno = DSO_LOAD_ERRNO__DECOMPRESSION_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) fd = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (!pathname || (fd < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) unlink(tmpbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (pathname && (fd >= 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) strlcpy(pathname, tmpbuf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) int dso__decompress_kmodule_fd(struct dso *dso, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return decompress_kmodule(dso, name, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) int dso__decompress_kmodule_path(struct dso *dso, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) char *pathname, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) int fd = decompress_kmodule(dso, name, pathname, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return fd >= 0 ? 0 : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * Parses kernel module specified in @path and updates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * @m argument like:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) * @comp - true if @path contains supported compression suffix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) * false otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * @kmod - true if @path contains '.ko' suffix in right position,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * false otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) * @name - if (@alloc_name && @kmod) is true, it contains strdup-ed base name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * of the kernel module without suffixes, otherwise strudup-ed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * base name of @path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) * @ext - if (@alloc_ext && @comp) is true, it contains strdup-ed string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * the compression suffix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * Returns 0 if there's no strdup error, -ENOMEM otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) int __kmod_path__parse(struct kmod_path *m, const char *path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) bool alloc_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) const char *name = strrchr(path, '/');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) const char *ext = strrchr(path, '.');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) bool is_simple_name = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) memset(m, 0x0, sizeof(*m));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) name = name ? name + 1 : path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * '.' is also a valid character for module name. For example:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * [aaa.bbb] is a valid module name. '[' should have higher
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) * priority than '.ko' suffix.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) * The kernel names are from machine__mmap_name. Such
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * name should belong to kernel itself, not kernel module.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (name[0] == '[') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) is_simple_name = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if ((strncmp(name, "[kernel.kallsyms]", 17) == 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) (strncmp(name, "[guest.kernel.kallsyms", 22) == 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) (strncmp(name, "[vdso]", 6) == 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) (strncmp(name, "[vdso32]", 8) == 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) (strncmp(name, "[vdsox32]", 9) == 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) (strncmp(name, "[vsyscall]", 10) == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) m->kmod = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) m->kmod = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) /* No extension, just return name. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if ((ext == NULL) || is_simple_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (alloc_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) m->name = strdup(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) return m->name ? 0 : -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) m->comp = is_supported_compression(ext + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (m->comp > COMP_ID__NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) ext -= 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) /* Check .ko extension only if there's enough name left. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (ext > name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) m->kmod = !strncmp(ext, ".ko", 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (alloc_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (m->kmod) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (asprintf(&m->name, "[%.*s]", (int) (ext - name), name) == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (asprintf(&m->name, "%s", name) == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) strreplace(m->name, '-', '_');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) void dso__set_module_info(struct dso *dso, struct kmod_path *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (machine__is_host(machine))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) dso->symtab_type = DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) dso->symtab_type = DSO_BINARY_TYPE__GUEST_KMODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) /* _KMODULE_COMP should be next to _KMODULE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (m->kmod && m->comp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) dso->symtab_type++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) dso->comp = m->comp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) dso__set_short_name(dso, strdup(m->name), true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) * Global list of open DSOs and the counter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) static LIST_HEAD(dso__data_open);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) static long dso__data_open_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) static pthread_mutex_t dso__data_open_lock = PTHREAD_MUTEX_INITIALIZER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) static void dso__list_add(struct dso *dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) list_add_tail(&dso->data.open_entry, &dso__data_open);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) dso__data_open_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) static void dso__list_del(struct dso *dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) list_del_init(&dso->data.open_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) WARN_ONCE(dso__data_open_cnt <= 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) "DSO data fd counter out of bounds.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) dso__data_open_cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) static void close_first_dso(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) static int do_open(char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) int fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) char sbuf[STRERR_BUFSIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) fd = open(name, O_RDONLY|O_CLOEXEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (fd >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) pr_debug("dso open failed: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) str_error_r(errno, sbuf, sizeof(sbuf)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (!dso__data_open_cnt || errno != EMFILE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) close_first_dso();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) } while (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) static int __open_dso(struct dso *dso, struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) int fd = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) char *root_dir = (char *)"";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) char *name = malloc(PATH_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) bool decomp = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) root_dir = machine->root_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (dso__read_binary_type_filename(dso, dso->binary_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) root_dir, name, PATH_MAX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (!is_regular_file(name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (dso__needs_decompress(dso)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) char newpath[KMOD_DECOMP_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) size_t len = sizeof(newpath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if (dso__decompress_kmodule_path(dso, name, newpath, len) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) fd = -dso->load_errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) decomp = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) strcpy(name, newpath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) fd = do_open(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (decomp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) unlink(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) free(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) static void check_data_close(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) * dso_close - Open DSO data file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) * @dso: dso object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) * Open @dso's data file descriptor and updates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) * list/count of open DSO objects.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) static int open_dso(struct dso *dso, struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) int fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) struct nscookie nsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (dso->binary_type != DSO_BINARY_TYPE__BUILD_ID_CACHE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) nsinfo__mountns_enter(dso->nsinfo, &nsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) fd = __open_dso(dso, machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (dso->binary_type != DSO_BINARY_TYPE__BUILD_ID_CACHE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) nsinfo__mountns_exit(&nsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (fd >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) dso__list_add(dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * Check if we crossed the allowed number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) * of opened DSOs and close one if needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) check_data_close();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) return fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) static void close_data_fd(struct dso *dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (dso->data.fd >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) close(dso->data.fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) dso->data.fd = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) dso->data.file_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) dso__list_del(dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) * dso_close - Close DSO data file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) * @dso: dso object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) * Close @dso's data file descriptor and updates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) * list/count of open DSO objects.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) static void close_dso(struct dso *dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) close_data_fd(dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) static void close_first_dso(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) struct dso *dso;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) dso = list_first_entry(&dso__data_open, struct dso, data.open_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) close_dso(dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) static rlim_t get_fd_limit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) struct rlimit l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) rlim_t limit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) /* Allow half of the current open fd limit. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (getrlimit(RLIMIT_NOFILE, &l) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (l.rlim_cur == RLIM_INFINITY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) limit = l.rlim_cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) limit = l.rlim_cur / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) pr_err("failed to get fd limit\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) limit = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) static rlim_t fd_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) * Used only by tests/dso-data.c to reset the environment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) * for tests. I dont expect we should change this during
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) * standard runtime.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) void reset_fd_limit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) fd_limit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) static bool may_cache_fd(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (!fd_limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) fd_limit = get_fd_limit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if (fd_limit == RLIM_INFINITY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) return fd_limit > (rlim_t) dso__data_open_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) * Check and close LRU dso if we crossed allowed limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) * for opened dso file descriptors. The limit is half
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) * of the RLIMIT_NOFILE files opened.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) static void check_data_close(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) bool cache_fd = may_cache_fd();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (!cache_fd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) close_first_dso();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) * dso__data_close - Close DSO data file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) * @dso: dso object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) * External interface to close @dso's data file descriptor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) void dso__data_close(struct dso *dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) pthread_mutex_lock(&dso__data_open_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) close_dso(dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) pthread_mutex_unlock(&dso__data_open_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) static void try_to_open_dso(struct dso *dso, struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) enum dso_binary_type binary_type_data[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) DSO_BINARY_TYPE__BUILD_ID_CACHE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) DSO_BINARY_TYPE__NOT_FOUND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (dso->data.fd >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if (dso->binary_type != DSO_BINARY_TYPE__NOT_FOUND) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) dso->data.fd = open_dso(dso, machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) dso->binary_type = binary_type_data[i++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) dso->data.fd = open_dso(dso, machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if (dso->data.fd >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) } while (dso->binary_type != DSO_BINARY_TYPE__NOT_FOUND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (dso->data.fd >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) dso->data.status = DSO_DATA_STATUS_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) dso->data.status = DSO_DATA_STATUS_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) * dso__data_get_fd - Get dso's data file descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) * @dso: dso object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) * @machine: machine object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) * External interface to find dso's file, open it and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * returns file descriptor. It should be paired with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) * dso__data_put_fd() if it returns non-negative value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) int dso__data_get_fd(struct dso *dso, struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (dso->data.status == DSO_DATA_STATUS_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (pthread_mutex_lock(&dso__data_open_lock) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) try_to_open_dso(dso, machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if (dso->data.fd < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) pthread_mutex_unlock(&dso__data_open_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) return dso->data.fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) void dso__data_put_fd(struct dso *dso __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) pthread_mutex_unlock(&dso__data_open_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) bool dso__data_status_seen(struct dso *dso, enum dso_data_status_seen by)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) u32 flag = 1 << by;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (dso->data.status_seen & flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) dso->data.status_seen |= flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) static ssize_t bpf_read(struct dso *dso, u64 offset, char *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) struct bpf_prog_info_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) ssize_t size = DSO__DATA_CACHE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) u64 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) node = perf_env__find_bpf_prog_info(dso->bpf_prog.env, dso->bpf_prog.id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (!node || !node->info_linear) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) dso->data.status = DSO_DATA_STATUS_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) len = node->info_linear->info.jited_prog_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) buf = (u8 *)(uintptr_t)node->info_linear->info.jited_prog_insns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (offset >= len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) size = (ssize_t)min(len - offset, (u64)size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) memcpy(data, buf + offset, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) static int bpf_size(struct dso *dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) struct bpf_prog_info_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) node = perf_env__find_bpf_prog_info(dso->bpf_prog.env, dso->bpf_prog.id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) if (!node || !node->info_linear) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) dso->data.status = DSO_DATA_STATUS_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) dso->data.file_size = node->info_linear->info.jited_prog_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) dso_cache__free(struct dso *dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) struct rb_root *root = &dso->data.cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) struct rb_node *next = rb_first(root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) pthread_mutex_lock(&dso->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) while (next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) struct dso_cache *cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) cache = rb_entry(next, struct dso_cache, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) next = rb_next(&cache->rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) rb_erase(&cache->rb_node, root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) free(cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) pthread_mutex_unlock(&dso->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) static struct dso_cache *__dso_cache__find(struct dso *dso, u64 offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) const struct rb_root *root = &dso->data.cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) struct rb_node * const *p = &root->rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) const struct rb_node *parent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) struct dso_cache *cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) while (*p != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) u64 end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) parent = *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) cache = rb_entry(parent, struct dso_cache, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) end = cache->offset + DSO__DATA_CACHE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (offset < cache->offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) p = &(*p)->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) else if (offset >= end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) p = &(*p)->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) return cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) static struct dso_cache *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) dso_cache__insert(struct dso *dso, struct dso_cache *new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) struct rb_root *root = &dso->data.cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) struct rb_node **p = &root->rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) struct rb_node *parent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) struct dso_cache *cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) u64 offset = new->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) pthread_mutex_lock(&dso->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) while (*p != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) u64 end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) parent = *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) cache = rb_entry(parent, struct dso_cache, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) end = cache->offset + DSO__DATA_CACHE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) if (offset < cache->offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) p = &(*p)->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) else if (offset >= end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) p = &(*p)->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) rb_link_node(&new->rb_node, parent, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) rb_insert_color(&new->rb_node, root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) cache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) pthread_mutex_unlock(&dso->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) return cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) static ssize_t dso_cache__memcpy(struct dso_cache *cache, u64 offset, u8 *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) u64 size, bool out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) u64 cache_offset = offset - cache->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) u64 cache_size = min(cache->size - cache_offset, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) if (out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) memcpy(data, cache->data + cache_offset, cache_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) memcpy(cache->data + cache_offset, data, cache_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) return cache_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) static ssize_t file_read(struct dso *dso, struct machine *machine,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) u64 offset, char *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) pthread_mutex_lock(&dso__data_open_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) * dso->data.fd might be closed if other thread opened another
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) * file (dso) due to open file limit (RLIMIT_NOFILE).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) try_to_open_dso(dso, machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if (dso->data.fd < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) dso->data.status = DSO_DATA_STATUS_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) ret = pread(dso->data.fd, data, DSO__DATA_CACHE_SIZE, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) pthread_mutex_unlock(&dso__data_open_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) static struct dso_cache *dso_cache__populate(struct dso *dso,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) struct machine *machine,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) u64 offset, ssize_t *ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) u64 cache_offset = offset & DSO__DATA_CACHE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) struct dso_cache *cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) struct dso_cache *old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) cache = zalloc(sizeof(*cache) + DSO__DATA_CACHE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) if (!cache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) *ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) if (dso->binary_type == DSO_BINARY_TYPE__BPF_PROG_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) *ret = bpf_read(dso, cache_offset, cache->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) else if (dso->binary_type == DSO_BINARY_TYPE__OOL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) *ret = DSO__DATA_CACHE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) *ret = file_read(dso, machine, cache_offset, cache->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) if (*ret <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) free(cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) cache->offset = cache_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) cache->size = *ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) old = dso_cache__insert(dso, cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) if (old) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) /* we lose the race */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) free(cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) cache = old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) return cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) static struct dso_cache *dso_cache__find(struct dso *dso,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) struct machine *machine,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) u64 offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) ssize_t *ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) struct dso_cache *cache = __dso_cache__find(dso, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) return cache ? cache : dso_cache__populate(dso, machine, offset, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) static ssize_t dso_cache_io(struct dso *dso, struct machine *machine,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) u64 offset, u8 *data, ssize_t size, bool out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) struct dso_cache *cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) ssize_t ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) cache = dso_cache__find(dso, machine, offset, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (!cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) return dso_cache__memcpy(cache, offset, data, size, out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) * Reads and caches dso data DSO__DATA_CACHE_SIZE size chunks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) * in the rb_tree. Any read to already cached data is served
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) * by cached data. Writes update the cache only, not the backing file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) static ssize_t cached_io(struct dso *dso, struct machine *machine,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) u64 offset, u8 *data, ssize_t size, bool out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) ssize_t r = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) u8 *p = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) ret = dso_cache_io(dso, machine, offset, p, size, out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) /* Reached EOF, return what we have. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) BUG_ON(ret > size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) r += ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) p += ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) offset += ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) size -= ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) } while (size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) static int file_size(struct dso *dso, struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) struct stat st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) char sbuf[STRERR_BUFSIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) pthread_mutex_lock(&dso__data_open_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) * dso->data.fd might be closed if other thread opened another
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) * file (dso) due to open file limit (RLIMIT_NOFILE).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) try_to_open_dso(dso, machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (dso->data.fd < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) dso->data.status = DSO_DATA_STATUS_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) if (fstat(dso->data.fd, &st) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) pr_err("dso cache fstat failed: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) str_error_r(errno, sbuf, sizeof(sbuf)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) dso->data.status = DSO_DATA_STATUS_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) dso->data.file_size = st.st_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) pthread_mutex_unlock(&dso__data_open_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) int dso__data_file_size(struct dso *dso, struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) if (dso->data.file_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) if (dso->data.status == DSO_DATA_STATUS_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) if (dso->binary_type == DSO_BINARY_TYPE__BPF_PROG_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) return bpf_size(dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) return file_size(dso, machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) * dso__data_size - Return dso data size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) * @dso: dso object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) * @machine: machine object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) * Return: dso data size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) off_t dso__data_size(struct dso *dso, struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) if (dso__data_file_size(dso, machine))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) /* For now just estimate dso data size is close to file size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) return dso->data.file_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) static ssize_t data_read_write_offset(struct dso *dso, struct machine *machine,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) u64 offset, u8 *data, ssize_t size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) bool out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) if (dso__data_file_size(dso, machine))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) /* Check the offset sanity. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) if (offset > dso->data.file_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) if (offset + size < offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) return cached_io(dso, machine, offset, data, size, out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) * dso__data_read_offset - Read data from dso file offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) * @dso: dso object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) * @machine: machine object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) * @offset: file offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) * @data: buffer to store data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) * @size: size of the @data buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) * External interface to read data from dso file offset. Open
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) * dso data file and use cached_read to get the data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) u64 offset, u8 *data, ssize_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) if (dso->data.status == DSO_DATA_STATUS_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) return data_read_write_offset(dso, machine, offset, data, size, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) * dso__data_read_addr - Read data from dso address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) * @dso: dso object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) * @machine: machine object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) * @add: virtual memory address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) * @data: buffer to store data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) * @size: size of the @data buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) * External interface to read data from dso address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) ssize_t dso__data_read_addr(struct dso *dso, struct map *map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) struct machine *machine, u64 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) u8 *data, ssize_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) u64 offset = map->map_ip(map, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) return dso__data_read_offset(dso, machine, offset, data, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) * dso__data_write_cache_offs - Write data to dso data cache at file offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) * @dso: dso object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) * @machine: machine object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) * @offset: file offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) * @data: buffer to write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) * @size: size of the @data buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) * Write into the dso file data cache, but do not change the file itself.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) ssize_t dso__data_write_cache_offs(struct dso *dso, struct machine *machine,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) u64 offset, const u8 *data_in, ssize_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) u8 *data = (u8 *)data_in; /* cast away const to use same fns for r/w */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) if (dso->data.status == DSO_DATA_STATUS_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) return data_read_write_offset(dso, machine, offset, data, size, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) * dso__data_write_cache_addr - Write data to dso data cache at dso address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) * @dso: dso object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) * @machine: machine object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) * @add: virtual memory address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) * @data: buffer to write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) * @size: size of the @data buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) * External interface to write into the dso file data cache, but do not change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) * the file itself.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) ssize_t dso__data_write_cache_addr(struct dso *dso, struct map *map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) struct machine *machine, u64 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) const u8 *data, ssize_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) u64 offset = map->map_ip(map, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) return dso__data_write_cache_offs(dso, machine, offset, data, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) struct map *dso__new_map(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) struct map *map = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) struct dso *dso = dso__new(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) if (dso) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) map = map__new2(0, dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) dso__put(dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) return map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) struct dso *machine__findnew_kernel(struct machine *machine, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) const char *short_name, int dso_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) * The kernel dso could be created by build_id processing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) struct dso *dso = machine__findnew_dso(machine, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) * We need to run this in all cases, since during the build_id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) * processing we had no idea this was the kernel dso.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) if (dso != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) dso__set_short_name(dso, short_name, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) dso->kernel = dso_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) return dso;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) static void dso__set_long_name_id(struct dso *dso, const char *name, struct dso_id *id, bool name_allocated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) struct rb_root *root = dso->root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) if (name == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) if (dso->long_name_allocated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) free((char *)dso->long_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) if (root) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) rb_erase(&dso->rb_node, root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) * __dsos__findnew_link_by_longname_id() isn't guaranteed to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) * add it back, so a clean removal is required here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) RB_CLEAR_NODE(&dso->rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) dso->root = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) dso->long_name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) dso->long_name_len = strlen(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) dso->long_name_allocated = name_allocated;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) if (root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) __dsos__findnew_link_by_longname_id(root, dso, NULL, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) void dso__set_long_name(struct dso *dso, const char *name, bool name_allocated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) dso__set_long_name_id(dso, name, NULL, name_allocated);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) void dso__set_short_name(struct dso *dso, const char *name, bool name_allocated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) if (name == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) if (dso->short_name_allocated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) free((char *)dso->short_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) dso->short_name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) dso->short_name_len = strlen(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) dso->short_name_allocated = name_allocated;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) int dso__name_len(const struct dso *dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) if (!dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) return strlen("[unknown]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) if (verbose > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) return dso->long_name_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) return dso->short_name_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) bool dso__loaded(const struct dso *dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) return dso->loaded;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) bool dso__sorted_by_name(const struct dso *dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) return dso->sorted_by_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) void dso__set_sorted_by_name(struct dso *dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) dso->sorted_by_name = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) struct dso *dso__new_id(const char *name, struct dso_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) struct dso *dso = calloc(1, sizeof(*dso) + strlen(name) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) if (dso != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) strcpy(dso->name, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) if (id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) dso->id = *id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) dso__set_long_name_id(dso, dso->name, id, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) dso__set_short_name(dso, dso->name, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) dso->symbols = dso->symbol_names = RB_ROOT_CACHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) dso->data.cache = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) dso->inlined_nodes = RB_ROOT_CACHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) dso->srclines = RB_ROOT_CACHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) dso->data.fd = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) dso->data.status = DSO_DATA_STATUS_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) dso->binary_type = DSO_BINARY_TYPE__NOT_FOUND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) dso->is_64_bit = (sizeof(void *) == 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) dso->loaded = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) dso->rel = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) dso->sorted_by_name = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) dso->has_build_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) dso->has_srcline = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) dso->a2l_fails = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) dso->kernel = DSO_SPACE__USER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) dso->needs_swap = DSO_SWAP__UNSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) dso->comp = COMP_ID__NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) RB_CLEAR_NODE(&dso->rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) dso->root = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) INIT_LIST_HEAD(&dso->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) INIT_LIST_HEAD(&dso->data.open_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) pthread_mutex_init(&dso->lock, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) refcount_set(&dso->refcnt, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) return dso;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) struct dso *dso__new(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) return dso__new_id(name, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) void dso__delete(struct dso *dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) if (!RB_EMPTY_NODE(&dso->rb_node))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) pr_err("DSO %s is still in rbtree when being deleted!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) dso->long_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) /* free inlines first, as they reference symbols */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) inlines__tree_delete(&dso->inlined_nodes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) srcline__tree_delete(&dso->srclines);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) symbols__delete(&dso->symbols);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) if (dso->short_name_allocated) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) zfree((char **)&dso->short_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) dso->short_name_allocated = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) if (dso->long_name_allocated) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) zfree((char **)&dso->long_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) dso->long_name_allocated = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) dso__data_close(dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) auxtrace_cache__free(dso->auxtrace_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) dso_cache__free(dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) dso__free_a2l(dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) zfree(&dso->symsrc_filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) nsinfo__zput(dso->nsinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) pthread_mutex_destroy(&dso->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) free(dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) struct dso *dso__get(struct dso *dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) if (dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) refcount_inc(&dso->refcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) return dso;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) void dso__put(struct dso *dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) if (dso && refcount_dec_and_test(&dso->refcnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) dso__delete(dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) void dso__set_build_id(struct dso *dso, struct build_id *bid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) dso->bid = *bid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) dso->has_build_id = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) bool dso__build_id_equal(const struct dso *dso, struct build_id *bid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) if (dso->bid.size > bid->size && dso->bid.size == BUILD_ID_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) * For the backward compatibility, it allows a build-id has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) * trailing zeros.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) return !memcmp(dso->bid.data, bid->data, bid->size) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) !memchr_inv(&dso->bid.data[bid->size], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) dso->bid.size - bid->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) return dso->bid.size == bid->size &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) memcmp(dso->bid.data, bid->data, dso->bid.size) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) char path[PATH_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) if (machine__is_default_guest(machine))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) sprintf(path, "%s/sys/kernel/notes", machine->root_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) if (sysfs__read_build_id(path, &dso->bid) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) dso->has_build_id = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) int dso__kernel_module_get_build_id(struct dso *dso,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) const char *root_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) char filename[PATH_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) * kernel module short names are of the form "[module]" and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) * we need just "module" here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) const char *name = dso->short_name + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) snprintf(filename, sizeof(filename),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) "%s/sys/module/%.*s/notes/.note.gnu.build-id",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) root_dir, (int)strlen(name) - 1, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) if (sysfs__read_build_id(filename, &dso->bid) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) dso->has_build_id = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) static size_t dso__fprintf_buildid(struct dso *dso, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) char sbuild_id[SBUILD_ID_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) build_id__sprintf(&dso->bid, sbuild_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) return fprintf(fp, "%s", sbuild_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) size_t dso__fprintf(struct dso *dso, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) struct rb_node *nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) size_t ret = fprintf(fp, "dso: %s (", dso->short_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) if (dso->short_name != dso->long_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) ret += fprintf(fp, "%s, ", dso->long_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) ret += fprintf(fp, "%sloaded, ", dso__loaded(dso) ? "" : "NOT ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) ret += dso__fprintf_buildid(dso, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) ret += fprintf(fp, ")\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) for (nd = rb_first_cached(&dso->symbols); nd; nd = rb_next(nd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) ret += symbol__fprintf(pos, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) enum dso_type dso__type(struct dso *dso, struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) int fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) enum dso_type type = DSO__TYPE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) fd = dso__data_get_fd(dso, machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) if (fd >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) type = dso__type_fd(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) dso__data_put_fd(dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) int dso__strerror_load(struct dso *dso, char *buf, size_t buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) int idx, errnum = dso->load_errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) * This must have a same ordering as the enum dso_load_errno.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) static const char *dso_load__error_str[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) "Internal tools/perf/ library error",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) "Invalid ELF file",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) "Can not read build id",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) "Mismatching build id",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) "Decompression failure",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) BUG_ON(buflen == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) if (errnum >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) const char *err = str_error_r(errnum, buf, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) if (err != buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) scnprintf(buf, buflen, "%s", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) if (errnum < __DSO_LOAD_ERRNO__START || errnum >= __DSO_LOAD_ERRNO__END)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) idx = errnum - __DSO_LOAD_ERRNO__START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) scnprintf(buf, buflen, "%s", dso_load__error_str[idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) }