1c34984b2SArnaldo Carvalho de Melo /* 2c34984b2SArnaldo Carvalho de Melo * builtin-buildid-list.c 3c34984b2SArnaldo Carvalho de Melo * 47a6f205dSArnaldo Carvalho de Melo * Builtin buildid-list command: list buildids in perf.data, in the running 57a6f205dSArnaldo Carvalho de Melo * kernel and in ELF files. 6c34984b2SArnaldo Carvalho de Melo * 7c34984b2SArnaldo Carvalho de Melo * Copyright (C) 2009, Red Hat Inc. 8c34984b2SArnaldo Carvalho de Melo * Copyright (C) 2009, Arnaldo Carvalho de Melo <acme@redhat.com> 9c34984b2SArnaldo Carvalho de Melo */ 10c34984b2SArnaldo Carvalho de Melo #include "builtin.h" 117b2567c1SArnaldo Carvalho de Melo #include "util/build-id.h" 12c34984b2SArnaldo Carvalho de Melo #include "util/debug.h" 134a3cec84SArnaldo Carvalho de Melo #include "util/dso.h" 14a6bd98c4SBlake Jones #include "util/map.h" 15fa0d9846SArnaldo Carvalho de Melo #include <subcmd/pager.h> 164b6ab94eSJosh Poimboeuf #include <subcmd/parse-options.h> 1794c744b6SArnaldo Carvalho de Melo #include "util/session.h" 18c34984b2SArnaldo Carvalho de Melo #include "util/symbol.h" 19f5fc1412SJiri Olsa #include "util/data.h" 20f12ad272SIan Rogers #include "util/util.h" 21a43783aeSArnaldo Carvalho de Melo #include <errno.h> 22a6bd98c4SBlake Jones #include <inttypes.h> 236ef81c55SMamatha Inamdar #include <linux/err.h> 24c34984b2SArnaldo Carvalho de Melo 25a6bd98c4SBlake Jones static int buildid__map_cb(struct map *map, void *arg __maybe_unused) 26a6bd98c4SBlake Jones { 2763df0e4bSIan Rogers const struct dso *dso = map__dso(map); 28a6bd98c4SBlake Jones char bid_buf[SBUILD_ID_SIZE]; 29*ee756ef7SIan Rogers const char *dso_long_name = dso__long_name(dso); 30*ee756ef7SIan Rogers const char *dso_short_name = dso__short_name(dso); 31a6bd98c4SBlake Jones 32a6bd98c4SBlake Jones memset(bid_buf, 0, sizeof(bid_buf)); 33*ee756ef7SIan Rogers if (dso__has_build_id(dso)) 34*ee756ef7SIan Rogers build_id__sprintf(dso__bid_const(dso), bid_buf); 35e5116f46SIan Rogers printf("%s %16" PRIx64 " %16" PRIx64, bid_buf, map__start(map), map__end(map)); 36*ee756ef7SIan Rogers if (dso_long_name != NULL) 37*ee756ef7SIan Rogers printf(" %s", dso_long_name); 38*ee756ef7SIan Rogers else if (dso_short_name != NULL) 39*ee756ef7SIan Rogers printf(" %s", dso_short_name); 40*ee756ef7SIan Rogers 41a6bd98c4SBlake Jones printf("\n"); 42a6bd98c4SBlake Jones 43a6bd98c4SBlake Jones return 0; 44a6bd98c4SBlake Jones } 45a6bd98c4SBlake Jones 46a6bd98c4SBlake Jones static void buildid__show_kernel_maps(void) 47a6bd98c4SBlake Jones { 48a6bd98c4SBlake Jones struct machine *machine; 49a6bd98c4SBlake Jones 50a6bd98c4SBlake Jones machine = machine__new_host(); 51a6bd98c4SBlake Jones machine__for_each_kernel_map(machine, buildid__map_cb, NULL); 52a6bd98c4SBlake Jones machine__delete(machine); 53a6bd98c4SBlake Jones } 54a6bd98c4SBlake Jones 55f2add9cdSArnaldo Carvalho de Melo static int sysfs__fprintf_build_id(FILE *fp) 56f2add9cdSArnaldo Carvalho de Melo { 57d77fac7fSMasami Hiramatsu char sbuild_id[SBUILD_ID_SIZE]; 580b5a7935SMasami Hiramatsu int ret; 59f2add9cdSArnaldo Carvalho de Melo 600b5a7935SMasami Hiramatsu ret = sysfs__sprintf_build_id("/", sbuild_id); 610b5a7935SMasami Hiramatsu if (ret != sizeof(sbuild_id)) 620b5a7935SMasami Hiramatsu return ret < 0 ? ret : -EINVAL; 63f2add9cdSArnaldo Carvalho de Melo 640b5a7935SMasami Hiramatsu return fprintf(fp, "%s\n", sbuild_id); 65f2add9cdSArnaldo Carvalho de Melo } 66f2add9cdSArnaldo Carvalho de Melo 677a6f205dSArnaldo Carvalho de Melo static int filename__fprintf_build_id(const char *name, FILE *fp) 687a6f205dSArnaldo Carvalho de Melo { 69d77fac7fSMasami Hiramatsu char sbuild_id[SBUILD_ID_SIZE]; 700b5a7935SMasami Hiramatsu int ret; 717a6f205dSArnaldo Carvalho de Melo 720b5a7935SMasami Hiramatsu ret = filename__sprintf_build_id(name, sbuild_id); 730b5a7935SMasami Hiramatsu if (ret != sizeof(sbuild_id)) 740b5a7935SMasami Hiramatsu return ret < 0 ? ret : -EINVAL; 757a6f205dSArnaldo Carvalho de Melo 767a6f205dSArnaldo Carvalho de Melo return fprintf(fp, "%s\n", sbuild_id); 777a6f205dSArnaldo Carvalho de Melo } 787a6f205dSArnaldo Carvalho de Melo 79417c2ff6SArnaldo Carvalho de Melo static bool dso__skip_buildid(struct dso *dso, int with_hits) 80417c2ff6SArnaldo Carvalho de Melo { 81*ee756ef7SIan Rogers return with_hits && !dso__hit(dso); 82417c2ff6SArnaldo Carvalho de Melo } 83417c2ff6SArnaldo Carvalho de Melo 8470cb4e96SFeng Tang static int perf_session__list_build_ids(bool force, bool with_hits) 851b549504SRobert Richter { 861b549504SRobert Richter struct perf_session *session; 878ceb41d7SJiri Olsa struct perf_data data = { 88f5fc1412SJiri Olsa .path = input_name, 89f5fc1412SJiri Olsa .mode = PERF_DATA_MODE_READ, 90f5fc1412SJiri Olsa .force = force, 91f5fc1412SJiri Olsa }; 921b549504SRobert Richter 93166ccc9cSNamhyung Kim symbol__elf_init(); 94f0bf9107SArnaldo Carvalho de Melo /* 95f0bf9107SArnaldo Carvalho de Melo * See if this is an ELF file first: 96f0bf9107SArnaldo Carvalho de Melo */ 970b5a7935SMasami Hiramatsu if (filename__fprintf_build_id(input_name, stdout) > 0) 98f0bf9107SArnaldo Carvalho de Melo goto out; 99efad1415SRobert Richter 1002681bd85SNamhyung Kim session = perf_session__new(&data, &build_id__mark_dso_hit_ops); 1016ef81c55SMamatha Inamdar if (IS_ERR(session)) 1026ef81c55SMamatha Inamdar return PTR_ERR(session); 103cd10b289SAdrian Hunter 104cd10b289SAdrian Hunter /* 105cd10b289SAdrian Hunter * We take all buildids when the file contains AUX area tracing data 106cd10b289SAdrian Hunter * because we do not decode the trace because it would take too long. 107cd10b289SAdrian Hunter */ 1088ceb41d7SJiri Olsa if (!perf_data__is_pipe(&data) && 109cd10b289SAdrian Hunter perf_header__has_feat(&session->header, HEADER_AUXTRACE)) 110cd10b289SAdrian Hunter with_hits = false; 111cd10b289SAdrian Hunter 112d176db95SJiri Olsa if (!perf_header__has_feat(&session->header, HEADER_BUILD_ID)) 113d176db95SJiri Olsa with_hits = true; 114d176db95SJiri Olsa 115c67d7349SMilian Wolff if (zstd_init(&(session->zstd_data), 0) < 0) 116c67d7349SMilian Wolff pr_warning("Decompression initialization failed. Reported data may be incomplete.\n"); 117c67d7349SMilian Wolff 118299c3452SStephane Eranian /* 119299c3452SStephane Eranian * in pipe-mode, the only way to get the buildids is to parse 120299c3452SStephane Eranian * the record stream. Buildids are stored as RECORD_HEADER_BUILD_ID 121299c3452SStephane Eranian */ 1228ceb41d7SJiri Olsa if (with_hits || perf_data__is_pipe(&data)) 123b7b61cbeSArnaldo Carvalho de Melo perf_session__process_events(session); 1241b549504SRobert Richter 125417c2ff6SArnaldo Carvalho de Melo perf_session__fprintf_dsos_buildid(session, stdout, dso__skip_buildid, with_hits); 1261b549504SRobert Richter perf_session__delete(session); 127f0bf9107SArnaldo Carvalho de Melo out: 1281b549504SRobert Richter return 0; 1291b549504SRobert Richter } 1301b549504SRobert Richter 131b0ad8ea6SArnaldo Carvalho de Melo int cmd_buildid_list(int argc, const char **argv) 132c34984b2SArnaldo Carvalho de Melo { 1336ee41497SArnaldo Carvalho de Melo bool show_kernel = false; 134a6bd98c4SBlake Jones bool show_kernel_maps = false; 1356ee41497SArnaldo Carvalho de Melo bool with_hits = false; 1366ee41497SArnaldo Carvalho de Melo bool force = false; 1376ee41497SArnaldo Carvalho de Melo const struct option options[] = { 1386ee41497SArnaldo Carvalho de Melo OPT_BOOLEAN('H', "with-hits", &with_hits, "Show only DSOs with hits"), 1396ee41497SArnaldo Carvalho de Melo OPT_STRING('i', "input", &input_name, "file", "input file name"), 1406ee41497SArnaldo Carvalho de Melo OPT_BOOLEAN('f', "force", &force, "don't complain, do it"), 1416ee41497SArnaldo Carvalho de Melo OPT_BOOLEAN('k', "kernel", &show_kernel, "Show current kernel build id"), 142a6bd98c4SBlake Jones OPT_BOOLEAN('m', "kernel-maps", &show_kernel_maps, 143a6bd98c4SBlake Jones "Show build id of current kernel + modules"), 1446ee41497SArnaldo Carvalho de Melo OPT_INCR('v', "verbose", &verbose, "be more verbose"), 1456ee41497SArnaldo Carvalho de Melo OPT_END() 1466ee41497SArnaldo Carvalho de Melo }; 1476ee41497SArnaldo Carvalho de Melo const char * const buildid_list_usage[] = { 1486ee41497SArnaldo Carvalho de Melo "perf buildid-list [<options>]", 1496ee41497SArnaldo Carvalho de Melo NULL 1506ee41497SArnaldo Carvalho de Melo }; 1516ee41497SArnaldo Carvalho de Melo 152c34984b2SArnaldo Carvalho de Melo argc = parse_options(argc, argv, options, buildid_list_usage, 0); 153c34984b2SArnaldo Carvalho de Melo setup_pager(); 1546ee41497SArnaldo Carvalho de Melo 155a6bd98c4SBlake Jones if (show_kernel) { 156c8319c9dSMichael Petlan return !(sysfs__fprintf_build_id(stdout) > 0); 157a6bd98c4SBlake Jones } else if (show_kernel_maps) { 158a6bd98c4SBlake Jones buildid__show_kernel_maps(); 159a6bd98c4SBlake Jones return 0; 160a6bd98c4SBlake Jones } 1616ee41497SArnaldo Carvalho de Melo 16270cb4e96SFeng Tang return perf_session__list_build_ids(force, with_hits); 163c34984b2SArnaldo Carvalho de Melo } 164