xref: /OK3568_Linux_fs/kernel/tools/perf/builtin-buildid-list.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * builtin-buildid-list.c
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Builtin buildid-list command: list buildids in perf.data, in the running
5*4882a593Smuzhiyun  * kernel and in ELF files.
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Copyright (C) 2009, Red Hat Inc.
8*4882a593Smuzhiyun  * Copyright (C) 2009, Arnaldo Carvalho de Melo <acme@redhat.com>
9*4882a593Smuzhiyun  */
10*4882a593Smuzhiyun #include "builtin.h"
11*4882a593Smuzhiyun #include "perf.h"
12*4882a593Smuzhiyun #include "util/build-id.h"
13*4882a593Smuzhiyun #include "util/debug.h"
14*4882a593Smuzhiyun #include "util/dso.h"
15*4882a593Smuzhiyun #include <subcmd/pager.h>
16*4882a593Smuzhiyun #include <subcmd/parse-options.h>
17*4882a593Smuzhiyun #include "util/session.h"
18*4882a593Smuzhiyun #include "util/symbol.h"
19*4882a593Smuzhiyun #include "util/data.h"
20*4882a593Smuzhiyun #include <errno.h>
21*4882a593Smuzhiyun #include <linux/err.h>
22*4882a593Smuzhiyun 
sysfs__fprintf_build_id(FILE * fp)23*4882a593Smuzhiyun static int sysfs__fprintf_build_id(FILE *fp)
24*4882a593Smuzhiyun {
25*4882a593Smuzhiyun 	char sbuild_id[SBUILD_ID_SIZE];
26*4882a593Smuzhiyun 	int ret;
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun 	ret = sysfs__sprintf_build_id("/", sbuild_id);
29*4882a593Smuzhiyun 	if (ret != sizeof(sbuild_id))
30*4882a593Smuzhiyun 		return ret < 0 ? ret : -EINVAL;
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun 	return fprintf(fp, "%s\n", sbuild_id);
33*4882a593Smuzhiyun }
34*4882a593Smuzhiyun 
filename__fprintf_build_id(const char * name,FILE * fp)35*4882a593Smuzhiyun static int filename__fprintf_build_id(const char *name, FILE *fp)
36*4882a593Smuzhiyun {
37*4882a593Smuzhiyun 	char sbuild_id[SBUILD_ID_SIZE];
38*4882a593Smuzhiyun 	int ret;
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun 	ret = filename__sprintf_build_id(name, sbuild_id);
41*4882a593Smuzhiyun 	if (ret != sizeof(sbuild_id))
42*4882a593Smuzhiyun 		return ret < 0 ? ret : -EINVAL;
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun 	return fprintf(fp, "%s\n", sbuild_id);
45*4882a593Smuzhiyun }
46*4882a593Smuzhiyun 
dso__skip_buildid(struct dso * dso,int with_hits)47*4882a593Smuzhiyun static bool dso__skip_buildid(struct dso *dso, int with_hits)
48*4882a593Smuzhiyun {
49*4882a593Smuzhiyun 	return with_hits && !dso->hit;
50*4882a593Smuzhiyun }
51*4882a593Smuzhiyun 
perf_session__list_build_ids(bool force,bool with_hits)52*4882a593Smuzhiyun static int perf_session__list_build_ids(bool force, bool with_hits)
53*4882a593Smuzhiyun {
54*4882a593Smuzhiyun 	struct perf_session *session;
55*4882a593Smuzhiyun 	struct perf_data data = {
56*4882a593Smuzhiyun 		.path  = input_name,
57*4882a593Smuzhiyun 		.mode  = PERF_DATA_MODE_READ,
58*4882a593Smuzhiyun 		.force = force,
59*4882a593Smuzhiyun 	};
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun 	symbol__elf_init();
62*4882a593Smuzhiyun 	/*
63*4882a593Smuzhiyun 	 * See if this is an ELF file first:
64*4882a593Smuzhiyun 	 */
65*4882a593Smuzhiyun 	if (filename__fprintf_build_id(input_name, stdout) > 0)
66*4882a593Smuzhiyun 		goto out;
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun 	session = perf_session__new(&data, false, &build_id__mark_dso_hit_ops);
69*4882a593Smuzhiyun 	if (IS_ERR(session))
70*4882a593Smuzhiyun 		return PTR_ERR(session);
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun 	/*
73*4882a593Smuzhiyun 	 * We take all buildids when the file contains AUX area tracing data
74*4882a593Smuzhiyun 	 * because we do not decode the trace because it would take too long.
75*4882a593Smuzhiyun 	 */
76*4882a593Smuzhiyun 	if (!perf_data__is_pipe(&data) &&
77*4882a593Smuzhiyun 	    perf_header__has_feat(&session->header, HEADER_AUXTRACE))
78*4882a593Smuzhiyun 		with_hits = false;
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun 	/*
81*4882a593Smuzhiyun 	 * in pipe-mode, the only way to get the buildids is to parse
82*4882a593Smuzhiyun 	 * the record stream. Buildids are stored as RECORD_HEADER_BUILD_ID
83*4882a593Smuzhiyun 	 */
84*4882a593Smuzhiyun 	if (with_hits || perf_data__is_pipe(&data))
85*4882a593Smuzhiyun 		perf_session__process_events(session);
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun 	perf_session__fprintf_dsos_buildid(session, stdout, dso__skip_buildid, with_hits);
88*4882a593Smuzhiyun 	perf_session__delete(session);
89*4882a593Smuzhiyun out:
90*4882a593Smuzhiyun 	return 0;
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun 
cmd_buildid_list(int argc,const char ** argv)93*4882a593Smuzhiyun int cmd_buildid_list(int argc, const char **argv)
94*4882a593Smuzhiyun {
95*4882a593Smuzhiyun 	bool show_kernel = false;
96*4882a593Smuzhiyun 	bool with_hits = false;
97*4882a593Smuzhiyun 	bool force = false;
98*4882a593Smuzhiyun 	const struct option options[] = {
99*4882a593Smuzhiyun 	OPT_BOOLEAN('H', "with-hits", &with_hits, "Show only DSOs with hits"),
100*4882a593Smuzhiyun 	OPT_STRING('i', "input", &input_name, "file", "input file name"),
101*4882a593Smuzhiyun 	OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
102*4882a593Smuzhiyun 	OPT_BOOLEAN('k', "kernel", &show_kernel, "Show current kernel build id"),
103*4882a593Smuzhiyun 	OPT_INCR('v', "verbose", &verbose, "be more verbose"),
104*4882a593Smuzhiyun 	OPT_END()
105*4882a593Smuzhiyun 	};
106*4882a593Smuzhiyun 	const char * const buildid_list_usage[] = {
107*4882a593Smuzhiyun 		"perf buildid-list [<options>]",
108*4882a593Smuzhiyun 		NULL
109*4882a593Smuzhiyun 	};
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun 	argc = parse_options(argc, argv, options, buildid_list_usage, 0);
112*4882a593Smuzhiyun 	setup_pager();
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun 	if (show_kernel)
115*4882a593Smuzhiyun 		return !(sysfs__fprintf_build_id(stdout) > 0);
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun 	return perf_session__list_build_ids(force, with_hits);
118*4882a593Smuzhiyun }
119