diff options
Diffstat (limited to 'tools/perf/util/header.c')
| -rw-r--r-- | tools/perf/util/header.c | 361 | 
1 files changed, 10 insertions, 351 deletions
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 26f5b2fe5dc8..b20e40c74468 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -24,8 +24,6 @@  #include "build-id.h"  #include "data.h" -static bool no_buildid_cache = false; -  static u32 header_argc;  static const char **header_argv; @@ -79,10 +77,7 @@ static int do_write(int fd, const void *buf, size_t size)  	return 0;  } -#define NAME_ALIGN 64 - -static int write_padded(int fd, const void *bf, size_t count, -			size_t count_aligned) +int write_padded(int fd, const void *bf, size_t count, size_t count_aligned)  {  	static const char zero_buf[NAME_ALIGN];  	int err = do_write(fd, bf, count); @@ -171,340 +166,6 @@ perf_header__set_cmdline(int argc, const char **argv)  	return 0;  } -#define dsos__for_each_with_build_id(pos, head)	\ -	list_for_each_entry(pos, head, node)	\ -		if (!pos->has_build_id)		\ -			continue;		\ -		else - -static int write_buildid(const char *name, size_t name_len, u8 *build_id, -			 pid_t pid, u16 misc, int fd) -{ -	int err; -	struct build_id_event b; -	size_t len; - -	len = name_len + 1; -	len = PERF_ALIGN(len, NAME_ALIGN); - -	memset(&b, 0, sizeof(b)); -	memcpy(&b.build_id, build_id, BUILD_ID_SIZE); -	b.pid = pid; -	b.header.misc = misc; -	b.header.size = sizeof(b) + len; - -	err = do_write(fd, &b, sizeof(b)); -	if (err < 0) -		return err; - -	return write_padded(fd, name, name_len + 1, len); -} - -static int __dsos__hit_all(struct list_head *head) -{ -	struct dso *pos; - -	list_for_each_entry(pos, head, node) -		pos->hit = true; - -	return 0; -} - -static int machine__hit_all_dsos(struct machine *machine) -{ -	int err; - -	err = __dsos__hit_all(&machine->kernel_dsos.head); -	if (err) -		return err; - -	return __dsos__hit_all(&machine->user_dsos.head); -} - -int dsos__hit_all(struct perf_session *session) -{ -	struct rb_node *nd; -	int err; - -	err = machine__hit_all_dsos(&session->machines.host); -	if (err) -		return err; - -	for (nd = rb_first(&session->machines.guests); nd; nd = rb_next(nd)) { -		struct machine *pos = rb_entry(nd, struct machine, rb_node); - -		err = machine__hit_all_dsos(pos); -		if (err) -			return err; -	} - -	return 0; -} - -static int __dsos__write_buildid_table(struct list_head *head, -				       struct machine *machine, -				       pid_t pid, u16 misc, int fd) -{ -	char nm[PATH_MAX]; -	struct dso *pos; - -	dsos__for_each_with_build_id(pos, head) { -		int err; -		const char *name; -		size_t name_len; - -		if (!pos->hit) -			continue; - -		if (dso__is_vdso(pos)) { -			name = pos->short_name; -			name_len = pos->short_name_len + 1; -		} else if (dso__is_kcore(pos)) { -			machine__mmap_name(machine, nm, sizeof(nm)); -			name = nm; -			name_len = strlen(nm) + 1; -		} else { -			name = pos->long_name; -			name_len = pos->long_name_len + 1; -		} - -		err = write_buildid(name, name_len, pos->build_id, -				    pid, misc, fd); -		if (err) -			return err; -	} - -	return 0; -} - -static int machine__write_buildid_table(struct machine *machine, int fd) -{ -	int err; -	u16 kmisc = PERF_RECORD_MISC_KERNEL, -	    umisc = PERF_RECORD_MISC_USER; - -	if (!machine__is_host(machine)) { -		kmisc = PERF_RECORD_MISC_GUEST_KERNEL; -		umisc = PERF_RECORD_MISC_GUEST_USER; -	} - -	err = __dsos__write_buildid_table(&machine->kernel_dsos.head, machine, -					  machine->pid, kmisc, fd); -	if (err == 0) -		err = __dsos__write_buildid_table(&machine->user_dsos.head, -						  machine, machine->pid, umisc, -						  fd); -	return err; -} - -static int dsos__write_buildid_table(struct perf_header *header, int fd) -{ -	struct perf_session *session = container_of(header, -			struct perf_session, header); -	struct rb_node *nd; -	int err = machine__write_buildid_table(&session->machines.host, fd); - -	if (err) -		return err; - -	for (nd = rb_first(&session->machines.guests); nd; nd = rb_next(nd)) { -		struct machine *pos = rb_entry(nd, struct machine, rb_node); -		err = machine__write_buildid_table(pos, fd); -		if (err) -			break; -	} -	return err; -} - -int build_id_cache__add_s(const char *sbuild_id, const char *debugdir, -			  const char *name, bool is_kallsyms, bool is_vdso) -{ -	const size_t size = PATH_MAX; -	char *realname, *filename = zalloc(size), -	     *linkname = zalloc(size), *targetname; -	int len, err = -1; -	bool slash = is_kallsyms || is_vdso; - -	if (is_kallsyms) { -		if (symbol_conf.kptr_restrict) { -			pr_debug("Not caching a kptr_restrict'ed /proc/kallsyms\n"); -			err = 0; -			goto out_free; -		} -		realname = (char *) name; -	} else -		realname = realpath(name, NULL); - -	if (realname == NULL || filename == NULL || linkname == NULL) -		goto out_free; - -	len = scnprintf(filename, size, "%s%s%s", -		       debugdir, slash ? "/" : "", -		       is_vdso ? DSO__NAME_VDSO : realname); -	if (mkdir_p(filename, 0755)) -		goto out_free; - -	snprintf(filename + len, size - len, "/%s", sbuild_id); - -	if (access(filename, F_OK)) { -		if (is_kallsyms) { -			 if (copyfile("/proc/kallsyms", filename)) -				goto out_free; -		} else if (link(realname, filename) && copyfile(name, filename)) -			goto out_free; -	} - -	len = scnprintf(linkname, size, "%s/.build-id/%.2s", -		       debugdir, sbuild_id); - -	if (access(linkname, X_OK) && mkdir_p(linkname, 0755)) -		goto out_free; - -	snprintf(linkname + len, size - len, "/%s", sbuild_id + 2); -	targetname = filename + strlen(debugdir) - 5; -	memcpy(targetname, "../..", 5); - -	if (symlink(targetname, linkname) == 0) -		err = 0; -out_free: -	if (!is_kallsyms) -		free(realname); -	free(filename); -	free(linkname); -	return err; -} - -static int build_id_cache__add_b(const u8 *build_id, size_t build_id_size, -				 const char *name, const char *debugdir, -				 bool is_kallsyms, bool is_vdso) -{ -	char sbuild_id[BUILD_ID_SIZE * 2 + 1]; - -	build_id__sprintf(build_id, build_id_size, sbuild_id); - -	return build_id_cache__add_s(sbuild_id, debugdir, name, -				     is_kallsyms, is_vdso); -} - -int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir) -{ -	const size_t size = PATH_MAX; -	char *filename = zalloc(size), -	     *linkname = zalloc(size); -	int err = -1; - -	if (filename == NULL || linkname == NULL) -		goto out_free; - -	snprintf(linkname, size, "%s/.build-id/%.2s/%s", -		 debugdir, sbuild_id, sbuild_id + 2); - -	if (access(linkname, F_OK)) -		goto out_free; - -	if (readlink(linkname, filename, size - 1) < 0) -		goto out_free; - -	if (unlink(linkname)) -		goto out_free; - -	/* -	 * Since the link is relative, we must make it absolute: -	 */ -	snprintf(linkname, size, "%s/.build-id/%.2s/%s", -		 debugdir, sbuild_id, filename); - -	if (unlink(linkname)) -		goto out_free; - -	err = 0; -out_free: -	free(filename); -	free(linkname); -	return err; -} - -static int dso__cache_build_id(struct dso *dso, struct machine *machine, -			       const char *debugdir) -{ -	bool is_kallsyms = dso->kernel && dso->long_name[0] != '/'; -	bool is_vdso = dso__is_vdso(dso); -	const char *name = dso->long_name; -	char nm[PATH_MAX]; - -	if (dso__is_kcore(dso)) { -		is_kallsyms = true; -		machine__mmap_name(machine, nm, sizeof(nm)); -		name = nm; -	} -	return build_id_cache__add_b(dso->build_id, sizeof(dso->build_id), name, -				     debugdir, is_kallsyms, is_vdso); -} - -static int __dsos__cache_build_ids(struct list_head *head, -				   struct machine *machine, const char *debugdir) -{ -	struct dso *pos; -	int err = 0; - -	dsos__for_each_with_build_id(pos, head) -		if (dso__cache_build_id(pos, machine, debugdir)) -			err = -1; - -	return err; -} - -static int machine__cache_build_ids(struct machine *machine, const char *debugdir) -{ -	int ret = __dsos__cache_build_ids(&machine->kernel_dsos.head, machine, -					  debugdir); -	ret |= __dsos__cache_build_ids(&machine->user_dsos.head, machine, -				       debugdir); -	return ret; -} - -static int perf_session__cache_build_ids(struct perf_session *session) -{ -	struct rb_node *nd; -	int ret; -	char debugdir[PATH_MAX]; - -	snprintf(debugdir, sizeof(debugdir), "%s", buildid_dir); - -	if (mkdir(debugdir, 0755) != 0 && errno != EEXIST) -		return -1; - -	ret = machine__cache_build_ids(&session->machines.host, debugdir); - -	for (nd = rb_first(&session->machines.guests); nd; nd = rb_next(nd)) { -		struct machine *pos = rb_entry(nd, struct machine, rb_node); -		ret |= machine__cache_build_ids(pos, debugdir); -	} -	return ret ? -1 : 0; -} - -static bool machine__read_build_ids(struct machine *machine, bool with_hits) -{ -	bool ret; - -	ret  = __dsos__read_build_ids(&machine->kernel_dsos.head, with_hits); -	ret |= __dsos__read_build_ids(&machine->user_dsos.head, with_hits); -	return ret; -} - -static bool perf_session__read_build_ids(struct perf_session *session, bool with_hits) -{ -	struct rb_node *nd; -	bool ret = machine__read_build_ids(&session->machines.host, with_hits); - -	for (nd = rb_first(&session->machines.guests); nd; nd = rb_next(nd)) { -		struct machine *pos = rb_entry(nd, struct machine, rb_node); -		ret |= machine__read_build_ids(pos, with_hits); -	} - -	return ret; -} -  static int write_tracing_data(int fd, struct perf_header *h __maybe_unused,  			    struct perf_evlist *evlist)  { @@ -523,13 +184,12 @@ static int write_build_id(int fd, struct perf_header *h,  	if (!perf_session__read_build_ids(session, true))  		return -1; -	err = dsos__write_buildid_table(h, fd); +	err = perf_session__write_buildid_table(session, fd);  	if (err < 0) {  		pr_debug("failed to write buildid table\n");  		return err;  	} -	if (!no_buildid_cache) -		perf_session__cache_build_ids(session); +	perf_session__cache_build_ids(session);  	return 0;  } @@ -601,8 +261,10 @@ static int __write_cpudesc(int fd, const char *cpuinfo_proc)  			break;  	} -	if (ret) +	if (ret) { +		ret = -1;  		goto done; +	}  	s = buf; @@ -965,7 +627,8 @@ static int write_total_mem(int fd, struct perf_header *h __maybe_unused,  		n = sscanf(buf, "%*s %"PRIu64, &mem);  		if (n == 1)  			ret = do_write(fd, &mem, sizeof(mem)); -	} +	} else +		ret = -1;  	free(buf);  	fclose(fp);  	return ret; @@ -1603,7 +1266,7 @@ static int __event_process_build_id(struct build_id_event *bev,  		dso__set_build_id(dso, &bev->build_id); -		if (filename[0] == '[') +		if (!is_kernel_module(filename, NULL))  			dso->kernel = dso_type;  		build_id__sprintf(dso->build_id, sizeof(dso->build_id), @@ -2477,6 +2140,7 @@ static const int attr_file_abi_sizes[] = {  	[1] = PERF_ATTR_SIZE_VER1,  	[2] = PERF_ATTR_SIZE_VER2,  	[3] = PERF_ATTR_SIZE_VER3, +	[4] = PERF_ATTR_SIZE_VER4,  	0,  }; @@ -3124,8 +2788,3 @@ int perf_event__process_build_id(struct perf_tool *tool __maybe_unused,  				 session);  	return 0;  } - -void disable_buildid_cache(void) -{ -	no_buildid_cache = true; -}  |