15 #include <sys/types.h> 20 #include <linux/kernel.h> 45 pr_err(
"problem processing %d event, skipping it.\n",
86 .ordered_events =
true,
95 for (i = 0; i < len; ++i) {
96 sprintf(bid,
"%02x", *raw);
101 return (bid - bf) + 1;
113 scnprintf(notes,
sizeof(notes),
"%s/sys/kernel/notes", root_dir);
130 else if (ret !=
sizeof(build_id))
147 ret = vsnprintf(*strp, size, fmt, ap);
149 ret = vasprintf(strp, fmt, ap);
158 bool retry_old =
true;
160 snprintf(bf, size,
"%s/%s/%s/kallsyms",
163 if (!access(bf, F_OK))
167 snprintf(bf, size,
"%s/%s/%s",
180 sbuild_id, sbuild_id + 2);
181 if (ret < 0 || (tmp && size < (
unsigned int)ret))
190 char *ret = NULL, *p;
198 len = readlink(linkname, buf,
sizeof(buf) - 1);
204 p = strrchr(buf,
'/');
205 if (p && (p > buf + offs)) {
207 if (buf[offs + 1] ==
'[')
213 ret = strdup(buf + offs);
234 else if (pathname[0] ==
'/')
239 result = (strcmp(sbuild_id, real_sbuild_id) == 0);
248 return is_kallsyms ?
"kallsyms" : (is_vdso ?
"vdso" : (is_debug ?
259 bool alloc = (bf == NULL);
272 ret =
asnprintf(&bf, size,
"%s", linkname);
274 ret =
asnprintf(&bf, size,
"%s/%s", linkname,
277 if (ret < 0 || (!alloc && size < (
unsigned int)ret))
284 #define dsos__for_each_with_build_id(pos, head) \ 285 list_for_each_entry(pos, head, node) \ 286 if (!pos->has_build_id) \ 304 b.
header.size =
sizeof(b) + len;
318 u16 kmisc = PERF_RECORD_MISC_KERNEL,
319 umisc = PERF_RECORD_MISC_USER;
322 kmisc = PERF_RECORD_MISC_GUEST_KERNEL;
323 umisc = PERF_RECORD_MISC_GUEST_USER;
329 bool in_kernel =
false;
339 name_len = strlen(name);
345 in_kernel = pos->
kernel ||
347 PERF_RECORD_MISC_CPUMODE_UNKNOWN);
349 in_kernel ? kmisc : umisc, fd);
366 for (nd = rb_first(&session->
machines.
guests); nd; nd = rb_next(nd)) {
379 list_for_each_entry(pos, head,
node)
399 for (nd = rb_first(&session->
machines.
guests); nd; nd = rb_next(nd)) {
418 return (strlen(d->d_name) == 2) &&
433 struct strlist *toplist, *linklist = NULL, *bidlist;
435 char *topdir, *linkdir = NULL;
443 if (asprintf(&topdir,
"%s/.build-id/",
buildid_dir) < 0)
452 pr_debug(
"Error in lsdir(%s): %d\n", topdir, errno);
460 if (asprintf(&linkdir,
"%s/%s", topdir, nd->
s) < 0)
465 pr_debug(
"Error in lsdir(%s): %d\n", linkdir, errno);
500 for (i = 0; i < len; i++) {
512 char *sbuild_id = NULL;
513 size_t len = strlen(incomplete_sbuild_id);
524 if (strncmp(nd->
s, incomplete_sbuild_id, len) != 0)
533 sbuild_id = strdup(cand->
s);
543 char *realname = (
char *)name, *
filename;
544 bool slash = is_kallsyms || is_vdso;
554 sbuild_id ?
"/" :
"", sbuild_id ?:
"") < 0)
581 #if defined(HAVE_LIBELF_SUPPORT) && defined(HAVE_GELF_GETNOTE_SUPPORT) 583 const char *realname,
595 ret = probe_cache__scan_sdt(cache, realname);
598 pr_debug4(
"Found %d SDTs in %s\n", ret, realname);
606 #define build_id_cache__add_sdt_cache(sbuild_id, realname, nsi) (0) 612 char *realname = NULL;
622 "/usr/lib/debug/.build-id/");
623 snprintf(debugfile + len,
PATH_MAX - len,
"%.2s/%s.debug", sbuild_id,
627 realname = realpath(debugfile, NULL);
628 if (realname && access(realname, R_OK))
637 struct nsinfo *nsi,
bool is_kallsyms,
bool is_vdso)
640 char *realname = NULL, *
filename = NULL, *dir_name = NULL,
641 *linkname =
zalloc(size), *tmp;
642 char *debugfile = NULL;
649 realname = realpath(name, NULL);
661 if (unlink(dir_name))
668 if (asprintf(&filename,
"%s/%s", dir_name,
675 if (access(filename, F_OK)) {
677 if (
copyfile(
"/proc/kallsyms", filename))
682 }
else if (link(realname, filename) && errno != EEXIST &&
692 if (!is_kallsyms && !is_vdso &&
693 strncmp(
".ko", name + strlen(name) - 3, 3)) {
697 if (asprintf(&filename,
"%s/%s", dir_name,
702 if (access(filename, F_OK)) {
707 }
else if (link(debugfile, filename) &&
717 tmp = strrchr(linkname,
'/');
720 if (access(linkname, X_OK) &&
mkdir_p(linkname, 0755))
727 if (symlink(tmp, linkname) == 0)
733 pr_debug4(
"Failed to update/scan SDT cache for %s\n", realname);
747 bool is_kallsyms,
bool is_vdso)
762 if (filename && !access(filename, F_OK))
773 *linkname =
zalloc(size), *tmp;
776 if (filename == NULL || linkname == NULL)
782 if (access(linkname, F_OK))
785 if (readlink(linkname, filename, size - 1) < 0)
788 if (unlink(linkname))
794 tmp = strrchr(linkname,
'/') + 1;
795 snprintf(tmp, size - (tmp - linkname),
"%s", filename);
818 dso->
nsinfo, is_kallsyms, is_vdso);
847 if (mkdir(
buildid_dir, 0755) != 0 && errno != EEXIST)
852 for (nd = rb_first(&session->
machines.
guests); nd; nd = rb_next(nd)) {
869 for (nd = rb_first(&session->
machines.
guests); nd; nd = rb_next(nd)) {
char * build_id_cache__origname(const char *sbuild_id)
static int write_buildid(const char *name, size_t name_len, u8 *build_id, pid_t pid, u16 misc, struct feat_fd *fd)
char * build_id_cache__linkname(const char *sbuild_id, char *bf, size_t size)
static int machine__hit_all_dsos(struct machine *machine)
static bool build_id_cache__valid_id(char *sbuild_id)
void nsinfo__mountns_enter(struct nsinfo *nsi, struct nscookie *nc)
int perf_session__write_buildid_table(struct perf_session *session, struct feat_fd *fd)
bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
char * nsinfo__realpath(const char *path, struct nsinfo *nsi)
static bool machine__is_host(struct machine *machine)
int perf_event__process_mmap(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
int build_id_cache__add_s(const char *sbuild_id, const char *name, struct nsinfo *nsi, bool is_kallsyms, bool is_vdso)
void disable_buildid_cache(void)
static int build_id_cache__add_b(const u8 *build_id, size_t build_id_size, const char *name, struct nsinfo *nsi, bool is_kallsyms, bool is_vdso)
static int __symbol__join_symfs(char *bf, size_t size, const char *path)
static bool lsdir_bid_tail_filter(const char *name __maybe_unused, struct dirent *d)
struct map * thread__find_map(struct thread *thread, u8 cpumode, u64 addr, struct addr_location *al)
void machine__remove_thread(struct machine *machine, struct thread *th)
int strlist__add(struct strlist *slist, const char *new_entry)
int filename__read_build_id(const char *filename, void *bf, size_t size)
char * build_id_cache__kallsyms_path(const char *sbuild_id, char *bf, size_t size)
int build_id_cache__remove_s(const char *sbuild_id)
bool is_regular_file(const char *file)
int perf_event__process_fork(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
int dump_printf(const char *fmt,...)
static int perf_event__exit_del_thread(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample __maybe_unused, struct machine *machine)
bool perf_session__read_build_ids(struct perf_session *session, bool with_hits)
x86 movsq based memset() in arch/x86/lib/memset_64.S") MEMSET_FN(memset_erms
int rm_rf(const char *path)
static int dso__cache_build_id(struct dso *dso, struct machine *machine)
int copyfile_ns(const char *from, const char *to, struct nsinfo *nsi)
static int machine__cache_build_ids(struct machine *machine)
#define pr_debug4(fmt,...)
int dsos__hit_all(struct perf_session *session)
bool is_kernel_module(const char *pathname, int cpumode)
int build_id__mark_dso_hit(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct perf_evsel *evsel __maybe_unused, struct machine *machine)
u8 build_id[PERF_ALIGN(BUILD_ID_SIZE, sizeof(u64))]
static int __dsos__cache_build_ids(struct list_head *head, struct machine *machine)
void nsinfo__mountns_exit(struct nscookie *nc)
#define pr_debug(fmt,...)
static struct perf_session * session
#define dsos__for_each_with_build_id(pos, head)
struct perf_event_header header
static struct perf_tool tool
bool dso__is_vdso(struct dso *dso)
#define strlist__for_each_entry(pos, slist)
int filename__sprintf_build_id(const char *pathname, char *sbuild_id)
static bool dso__is_kallsyms(struct dso *dso)
static bool no_buildid_cache
struct probe_cache * probe_cache__new(const char *target, struct nsinfo *nsi)
static bool dso__is_kcore(struct dso *dso)
int sysfs__sprintf_build_id(const char *root_dir, char *sbuild_id)
enum dso_kernel_type kernel
#define DSO__NAME_KALLSYMS
x86 movsq based memcpy() in arch/x86/lib/memcpy_64.S") MEMCPY_FN(memcpy_erms
static bool lsdir_bid_head_filter(const char *name __maybe_unused, struct dirent *d)
int build_id_cache__list_build_ids(const char *pathname, struct nsinfo *nsi, struct strlist **result)
static int raw(yyscan_t scanner)
static int __dsos__hit_all(struct list_head *head)
int perf_session__cache_build_ids(struct perf_session *session)
void probe_cache__delete(struct probe_cache *pcache)
int mkdir_p(char *path, mode_t mode)
static struct rb_root result
struct perf_event_header header
static char * build_id_cache__find_debug(const char *sbuild_id, struct nsinfo *nsi)
static int asnprintf(char **strp, size_t size, const char *fmt,...)
int perf_event__process_mmap2(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
void thread__put(struct thread *thread)
int probe_cache__commit(struct probe_cache *pcache)
int copyfile(const char *from, const char *to)
struct perf_tool build_id__mark_dso_hit_ops
u8 build_id[BUILD_ID_SIZE]
char * build_id_cache__cachedir(const char *sbuild_id, const char *name, struct nsinfo *nsi, bool is_kallsyms, bool is_vdso)
bool build_id_cache__cached(const char *sbuild_id)
void strlist__delete(struct strlist *slist)
int build_id__sprintf(const u8 *build_id, int len, char *bf)
static bool str_is_build_id(const char *maybe_sbuild_id, size_t len)
int symbol__init(struct perf_env *env)
struct strlist * build_id_cache__list_all(bool validonly)
bool lsdir_no_dot_filter(const char *name __maybe_unused, struct dirent *d)
char * build_id_cache__complement(const char *incomplete_sbuild_id)
char * dso__build_id_filename(const struct dso *dso, char *bf, size_t size, bool is_debug)
int sysfs__read_build_id(const char *filename, void *build_id, size_t size)
struct strlist * lsdir(const char *name, bool(*filter)(const char *, struct dirent *))
static const char * build_id_cache__basename(bool is_kallsyms, bool is_vdso, bool is_debug)
static int machine__write_buildid_table(struct machine *machine, struct feat_fd *fd)
#define build_id_cache__add_sdt_cache(sbuild_id, realname, nsi)
struct strlist * strlist__new(const char *list, const struct strlist_config *config)
struct thread * machine__findnew_thread(struct machine *machine, pid_t pid, pid_t tid)
void static void * zalloc(size_t size)
static bool machine__read_build_ids(struct machine *machine, bool with_hits)