Home | History | Annotate | Download | only in perf
      1 /*
      2  * builtin-buildid-list.c
      3  *
      4  * Builtin buildid-list command: list buildids in perf.data, in the running
      5  * kernel and in ELF files.
      6  *
      7  * Copyright (C) 2009, Red Hat Inc.
      8  * Copyright (C) 2009, Arnaldo Carvalho de Melo <acme (at) redhat.com>
      9  */
     10 #include "builtin.h"
     11 #include "perf.h"
     12 #include "util/build-id.h"
     13 #include "util/cache.h"
     14 #include "util/debug.h"
     15 #include "util/parse-options.h"
     16 #include "util/session.h"
     17 #include "util/symbol.h"
     18 
     19 static int sysfs__fprintf_build_id(FILE *fp)
     20 {
     21 	u8 kallsyms_build_id[BUILD_ID_SIZE];
     22 	char sbuild_id[BUILD_ID_SIZE * 2 + 1];
     23 
     24 	if (sysfs__read_build_id("/sys/kernel/notes", kallsyms_build_id,
     25 				 sizeof(kallsyms_build_id)) != 0)
     26 		return -1;
     27 
     28 	build_id__sprintf(kallsyms_build_id, sizeof(kallsyms_build_id),
     29 			  sbuild_id);
     30 	fprintf(fp, "%s\n", sbuild_id);
     31 	return 0;
     32 }
     33 
     34 static int filename__fprintf_build_id(const char *name, FILE *fp)
     35 {
     36 	u8 build_id[BUILD_ID_SIZE];
     37 	char sbuild_id[BUILD_ID_SIZE * 2 + 1];
     38 
     39 	if (filename__read_build_id(name, build_id,
     40 				    sizeof(build_id)) != sizeof(build_id))
     41 		return 0;
     42 
     43 	build_id__sprintf(build_id, sizeof(build_id), sbuild_id);
     44 	return fprintf(fp, "%s\n", sbuild_id);
     45 }
     46 
     47 static bool dso__skip_buildid(struct dso *dso, int with_hits)
     48 {
     49 	return with_hits && !dso->hit;
     50 }
     51 
     52 static int perf_session__list_build_ids(bool force, bool with_hits)
     53 {
     54 	struct perf_session *session;
     55 
     56 	symbol__elf_init();
     57 	/*
     58 	 * See if this is an ELF file first:
     59 	 */
     60 	if (filename__fprintf_build_id(input_name, stdout))
     61 		goto out;
     62 
     63 	session = perf_session__new(input_name, O_RDONLY, force, false,
     64 				    &build_id__mark_dso_hit_ops);
     65 	if (session == NULL)
     66 		return -1;
     67 	/*
     68 	 * in pipe-mode, the only way to get the buildids is to parse
     69 	 * the record stream. Buildids are stored as RECORD_HEADER_BUILD_ID
     70 	 */
     71 	if (with_hits || session->fd_pipe)
     72 		perf_session__process_events(session, &build_id__mark_dso_hit_ops);
     73 
     74 	perf_session__fprintf_dsos_buildid(session, stdout, dso__skip_buildid, with_hits);
     75 	perf_session__delete(session);
     76 out:
     77 	return 0;
     78 }
     79 
     80 int cmd_buildid_list(int argc, const char **argv,
     81 		     const char *prefix __maybe_unused)
     82 {
     83 	bool show_kernel = false;
     84 	bool with_hits = false;
     85 	bool force = false;
     86 	const struct option options[] = {
     87 	OPT_BOOLEAN('H', "with-hits", &with_hits, "Show only DSOs with hits"),
     88 	OPT_STRING('i', "input", &input_name, "file", "input file name"),
     89 	OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
     90 	OPT_BOOLEAN('k', "kernel", &show_kernel, "Show current kernel build id"),
     91 	OPT_INCR('v', "verbose", &verbose, "be more verbose"),
     92 	OPT_END()
     93 	};
     94 	const char * const buildid_list_usage[] = {
     95 		"perf buildid-list [<options>]",
     96 		NULL
     97 	};
     98 
     99 	argc = parse_options(argc, argv, options, buildid_list_usage, 0);
    100 	setup_pager();
    101 
    102 	if (show_kernel)
    103 		return sysfs__fprintf_build_id(stdout);
    104 
    105 	return perf_session__list_build_ids(force, with_hits);
    106 }
    107