/*
 * builtin-buildid-list.c
 *
 * Builtin buildid-list command: list buildids in perf.data, in the running
 * kernel and in ELF files.
 *
 * Copyright (C) 2009, Red Hat Inc.
 * Copyright (C) 2009, Arnaldo Carvalho de Melo <acme@redhat.com>
 */
#include "builtin.h"
#include "util/build-id.h"
#include "util/debug.h"
#include "util/dso.h"
#include "util/map.h"
#include <subcmd/pager.h>
#include <subcmd/parse-options.h>
#include "util/session.h"
#include "util/symbol.h"
#include "util/data.h"
#include "util/util.h"
#include <errno.h>
#include <inttypes.h>
#include <linux/err.h>

static int buildid__map_cb(struct map *map, void *arg __maybe_unused)
{
	const struct dso *dso = map__dso(map);
	char bid_buf[SBUILD_ID_SIZE];
	const char *dso_long_name = dso__long_name(dso);
	const char *dso_short_name = dso__short_name(dso);

	memset(bid_buf, 0, sizeof(bid_buf));
	if (dso__has_build_id(dso))
		build_id__snprintf(dso__bid(dso), bid_buf, sizeof(bid_buf));
	printf("%s %16" PRIx64 " %16" PRIx64, bid_buf, map__start(map), map__end(map));
	if (dso_long_name != NULL)
		printf(" %s", dso_long_name);
	else if (dso_short_name != NULL)
		printf(" %s", dso_short_name);

	printf("\n");

	return 0;
}

static void buildid__show_kernel_maps(void)
{
	struct perf_env host_env;
	struct machine *machine;

	perf_env__init(&host_env);
	machine = machine__new_host(&host_env);
	machine__for_each_kernel_map(machine, buildid__map_cb, NULL);
	machine__delete(machine);
	perf_env__exit(&host_env);
}

static int sysfs__fprintf_build_id(FILE *fp)
{
	char sbuild_id[SBUILD_ID_SIZE];
	int ret;

	ret = sysfs__snprintf_build_id("/", sbuild_id, sizeof(sbuild_id));
	if (ret + 1 != sizeof(sbuild_id))
		return ret < 0 ? ret : -EINVAL;

	return fprintf(fp, "%s\n", sbuild_id);
}

static int filename__fprintf_build_id(const char *name, FILE *fp)
{
	char sbuild_id[SBUILD_ID_SIZE];
	int ret;

	ret = filename__snprintf_build_id(name, sbuild_id, sizeof(sbuild_id));
	if (ret + 1 != sizeof(sbuild_id))
		return ret < 0 ? ret : -EINVAL;

	return fprintf(fp, "%s\n", sbuild_id);
}

static bool dso__skip_buildid(struct dso *dso, int with_hits)
{
	return with_hits && !dso__hit(dso);
}

static int perf_session__list_build_ids(bool force, bool with_hits)
{
	struct perf_session *session;
	struct perf_data data = {
		.path  = input_name,
		.mode  = PERF_DATA_MODE_READ,
		.force = force,
	};
	struct perf_tool build_id__mark_dso_hit_ops;

	symbol__elf_init();
	/*
	 * See if this is an ELF file first:
	 */
	if (filename__fprintf_build_id(input_name, stdout) > 0)
		goto out;

	perf_tool__init(&build_id__mark_dso_hit_ops, /*ordered_events=*/true);
	build_id__mark_dso_hit_ops.sample	= build_id__mark_dso_hit;
	build_id__mark_dso_hit_ops.mmap		= perf_event__process_mmap;
	build_id__mark_dso_hit_ops.mmap2	= perf_event__process_mmap2;
	build_id__mark_dso_hit_ops.fork		= perf_event__process_fork;
	build_id__mark_dso_hit_ops.exit		= perf_event__exit_del_thread;
	build_id__mark_dso_hit_ops.attr		= perf_event__process_attr;
	build_id__mark_dso_hit_ops.build_id	= perf_event__process_build_id;

	session = perf_session__new(&data, &build_id__mark_dso_hit_ops);
	if (IS_ERR(session))
		return PTR_ERR(session);

	/*
	 * We take all buildids when the file contains AUX area tracing data
	 * because we do not decode the trace because it would take too long.
	 */
	if (!perf_data__is_pipe(&data) &&
	    perf_header__has_feat(&session->header, HEADER_AUXTRACE))
		with_hits = false;

	if (!perf_header__has_feat(&session->header, HEADER_BUILD_ID))
		with_hits = true;

	if (zstd_init(&(session->zstd_data), 0) < 0)
		pr_warning("Decompression initialization failed. Reported data may be incomplete.\n");

	/*
	 * in pipe-mode, the only way to get the buildids is to parse
	 * the record stream. Buildids are stored as RECORD_HEADER_BUILD_ID
	 */
	if (with_hits || perf_data__is_pipe(&data))
		perf_session__process_events(session);

	perf_session__fprintf_dsos_buildid(session, stdout, dso__skip_buildid, with_hits);
	perf_session__delete(session);
out:
	return 0;
}

int cmd_buildid_list(int argc, const char **argv)
{
	bool show_kernel = false;
	bool show_kernel_maps = false;
	bool with_hits = false;
	bool force = false;
	const struct option options[] = {
	OPT_BOOLEAN('H', "with-hits", &with_hits, "Show only DSOs with hits"),
	OPT_STRING('i', "input", &input_name, "file", "input file name"),
	OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
	OPT_BOOLEAN('k', "kernel", &show_kernel, "Show current kernel build id"),
	OPT_BOOLEAN('m', "kernel-maps", &show_kernel_maps,
	    "Show build id of current kernel + modules"),
	OPT_INCR('v', "verbose", &verbose, "be more verbose"),
	OPT_END()
	};
	const char * const buildid_list_usage[] = {
		"perf buildid-list [<options>]",
		NULL
	};

	argc = parse_options(argc, argv, options, buildid_list_usage, 0);
	setup_pager();

	if (show_kernel) {
		return !(sysfs__fprintf_build_id(stdout) > 0);
	} else if (show_kernel_maps) {
		buildid__show_kernel_maps();
		return 0;
	}

	return perf_session__list_build_ids(force, with_hits);
}
