// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2011, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
 *
 * Parts came from builtin-annotate.c, see those files for further
 * copyright notes.
 */

#include <errno.h>
#include <inttypes.h>
#include <libgen.h>
#include <stdlib.h>
#include "util.h" // hex_width()
#include "ui/ui.h"
#include "sort.h"
#include "build-id.h"
#include "color.h"
#include "config.h"
#include "disasm.h"
#include "dso.h"
#include "env.h"
#include "map.h"
#include "maps.h"
#include "symbol.h"
#include "srcline.h"
#include "units.h"
#include "debug.h"
#include "debuginfo.h"
#include "annotate.h"
#include "annotate-data.h"
#include "evsel.h"
#include "evlist.h"
#include "bpf-event.h"
#include "bpf-utils.h"
#include "block-range.h"
#include "string2.h"
#include "dwarf-regs.h"
#include "util/event.h"
#include "util/sharded_mutex.h"
#include "arch/common.h"
#include "namespaces.h"
#include "thread.h"
#include "hashmap.h"
#include "strbuf.h"
#include <regex.h>
#include <linux/bitops.h>
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/zalloc.h>
#include <subcmd/parse-options.h>
#include <subcmd/run-command.h>
#include <math.h>

/* FIXME: For the HE_COLORSET */
#include "ui/browser.h"

/*
 * FIXME: Using the same values as slang.h,
 * but that header may not be available everywhere
 */
#define LARROW_CHAR	((unsigned char)',')
#define RARROW_CHAR	((unsigned char)'+')
#define DARROW_CHAR	((unsigned char)'.')
#define UARROW_CHAR	((unsigned char)'-')

#include <linux/ctype.h>

/* global annotation options */
struct annotation_options annotate_opts;

/* Data type collection debug statistics */
struct annotated_data_stat ann_data_stat;
LIST_HEAD(ann_insn_stat);

/* Pseudo data types */
struct annotated_data_type stackop_type = {
	.self = {
		.type_name = (char *)"(stack operation)",
		.children = LIST_HEAD_INIT(stackop_type.self.children),
	},
};

struct annotated_data_type canary_type = {
	.self = {
		.type_name = (char *)"(stack canary)",
		.children = LIST_HEAD_INIT(canary_type.self.children),
	},
};

#define NO_TYPE ((struct annotated_data_type *)-1UL)

/* symbol histogram: key = offset << 16 | evsel->core.idx */
static size_t sym_hist_hash(long key, void *ctx __maybe_unused)
{
	return (key >> 16) + (key & 0xffff);
}

static bool sym_hist_equal(long key1, long key2, void *ctx __maybe_unused)
{
	return key1 == key2;
}

static struct annotated_source *annotated_source__new(void)
{
	struct annotated_source *src = zalloc(sizeof(*src));

	if (src != NULL)
		INIT_LIST_HEAD(&src->source);

	return src;
}

static __maybe_unused void annotated_source__delete(struct annotated_source *src)
{
	struct hashmap_entry *cur;
	size_t bkt;

	if (src == NULL)
		return;

	if (src->samples) {
		hashmap__for_each_entry(src->samples, cur, bkt)
			zfree(&cur->pvalue);
		hashmap__free(src->samples);
	}
	zfree(&src->histograms);
	free(src);
}

static int annotated_source__alloc_histograms(struct annotated_source *src,
					      int nr_hists)
{
	src->nr_histograms   = nr_hists;
	src->histograms	     = calloc(nr_hists, sizeof(*src->histograms));

	if (src->histograms == NULL)
		return -1;

	src->samples = hashmap__new(sym_hist_hash, sym_hist_equal, NULL);
	if (IS_ERR(src->samples)) {
		zfree(&src->histograms);
		src->samples = NULL;
	}

	return src->histograms ? 0 : -1;
}

void symbol__annotate_zero_histograms(struct symbol *sym)
{
	struct annotation *notes = symbol__annotation(sym);

	annotation__lock(notes);
	if (notes->src != NULL) {
		memset(notes->src->histograms, 0,
		       notes->src->nr_histograms * sizeof(*notes->src->histograms));
		hashmap__clear(notes->src->samples);
	}
	if (notes->branch && notes->branch->cycles_hist) {
		memset(notes->branch->cycles_hist, 0,
		       symbol__size(sym) * sizeof(struct cyc_hist));
	}
	annotation__unlock(notes);
}

static int __symbol__account_cycles(struct cyc_hist *ch,
				    u64 start,
				    unsigned offset, unsigned cycles,
				    unsigned have_start)
{
	/*
	 * For now we can only account one basic block per
	 * final jump. But multiple could be overlapping.
	 * Always account the longest one. So when
	 * a shorter one has been already seen throw it away.
	 *
	 * We separately always account the full cycles.
	 */
	ch[offset].num_aggr++;
	ch[offset].cycles_aggr += cycles;

	if (cycles > ch[offset].cycles_max)
		ch[offset].cycles_max = cycles;

	if (ch[offset].cycles_min) {
		if (cycles && cycles < ch[offset].cycles_min)
			ch[offset].cycles_min = cycles;
	} else
		ch[offset].cycles_min = cycles;

	if (!have_start && ch[offset].have_start)
		return 0;
	if (ch[offset].num) {
		if (have_start && (!ch[offset].have_start ||
				   ch[offset].start > start)) {
			ch[offset].have_start = 0;
			ch[offset].cycles = 0;
			ch[offset].num = 0;
			if (ch[offset].reset < 0xffff)
				ch[offset].reset++;
		} else if (have_start &&
			   ch[offset].start < start)
			return 0;
	}

	if (ch[offset].num < NUM_SPARKS)
		ch[offset].cycles_spark[ch[offset].num] = cycles;

	ch[offset].have_start = have_start;
	ch[offset].start = start;
	ch[offset].cycles += cycles;
	ch[offset].num++;
	return 0;
}

static int __symbol__inc_addr_samples(struct map_symbol *ms,
				      struct annotated_source *src, struct evsel *evsel, u64 addr,
				      struct perf_sample *sample)
{
	struct symbol *sym = ms->sym;
	long hash_key;
	u64 offset;
	struct sym_hist *h;
	struct sym_hist_entry *entry;

	pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map__unmap_ip(ms->map, addr));

	if ((addr < sym->start || addr >= sym->end) &&
	    (addr != sym->end || sym->start != sym->end)) {
		pr_debug("%s(%d): ERANGE! sym->name=%s, start=%#" PRIx64 ", addr=%#" PRIx64 ", end=%#" PRIx64 "\n",
		       __func__, __LINE__, sym->name, sym->start, addr, sym->end);
		return -ERANGE;
	}

	offset = addr - sym->start;
	h = annotated_source__histogram(src, evsel);
	if (h == NULL) {
		pr_debug("%s(%d): ENOMEM! sym->name=%s, start=%#" PRIx64 ", addr=%#" PRIx64 ", end=%#" PRIx64 ", func: %d\n",
			 __func__, __LINE__, sym->name, sym->start, addr, sym->end, sym->type == STT_FUNC);
		return -ENOMEM;
	}

	hash_key = offset << 16 | evsel->core.idx;
	if (!hashmap__find(src->samples, hash_key, &entry)) {
		entry = zalloc(sizeof(*entry));
		if (entry == NULL)
			return -ENOMEM;

		if (hashmap__add(src->samples, hash_key, entry) < 0)
			return -ENOMEM;
	}

	h->nr_samples++;
	h->period += sample->period;
	entry->nr_samples++;
	entry->period += sample->period;

	pr_debug3("%#" PRIx64 " %s: period++ [addr: %#" PRIx64 ", %#" PRIx64
		  ", evidx=%d] => nr_samples: %" PRIu64 ", period: %" PRIu64 "\n",
		  sym->start, sym->name, addr, addr - sym->start, evsel->core.idx,
		  entry->nr_samples, entry->period);
	return 0;
}

struct annotated_branch *annotation__get_branch(struct annotation *notes)
{
	if (notes == NULL)
		return NULL;

	if (notes->branch == NULL)
		notes->branch = zalloc(sizeof(*notes->branch));

	return notes->branch;
}

static struct annotated_branch *symbol__find_branch_hist(struct symbol *sym,
							 unsigned int br_cntr_nr)
{
	struct annotation *notes = symbol__annotation(sym);
	struct annotated_branch *branch;
	const size_t size = symbol__size(sym);

	branch = annotation__get_branch(notes);
	if (branch == NULL)
		return NULL;

	if (branch->cycles_hist == NULL) {
		branch->cycles_hist = calloc(size, sizeof(struct cyc_hist));
		if (!branch->cycles_hist)
			return NULL;
	}

	if (br_cntr_nr && branch->br_cntr == NULL) {
		branch->br_cntr = calloc(br_cntr_nr * size, sizeof(u64));
		if (!branch->br_cntr)
			return NULL;
	}

	return branch;
}

struct annotated_source *symbol__hists(struct symbol *sym, int nr_hists)
{
	struct annotation *notes = symbol__annotation(sym);

	if (notes->src == NULL) {
		notes->src = annotated_source__new();
		if (notes->src == NULL)
			return NULL;
		goto alloc_histograms;
	}

	if (notes->src->histograms == NULL) {
alloc_histograms:
		annotated_source__alloc_histograms(notes->src, nr_hists);
	}

	return notes->src;
}

static int symbol__inc_addr_samples(struct map_symbol *ms,
				    struct evsel *evsel, u64 addr,
				    struct perf_sample *sample)
{
	struct symbol *sym = ms->sym;
	struct annotated_source *src;

	if (sym == NULL)
		return 0;
	src = symbol__hists(sym, evsel->evlist->core.nr_entries);
	return src ? __symbol__inc_addr_samples(ms, src, evsel, addr, sample) : 0;
}

static int symbol__account_br_cntr(struct annotated_branch *branch,
				   struct evsel *evsel,
				   unsigned offset,
				   u64 br_cntr)
{
	unsigned int br_cntr_nr = evsel__leader(evsel)->br_cntr_nr;
	unsigned int base = evsel__leader(evsel)->br_cntr_idx;
	unsigned int off = offset * evsel->evlist->nr_br_cntr;
	u64 *branch_br_cntr = branch->br_cntr;
	unsigned int i, mask, width;

	if (!br_cntr || !branch_br_cntr)
		return 0;

	perf_env__find_br_cntr_info(evsel__env(evsel), NULL, &width);
	mask = (1L << width) - 1;
	for (i = 0; i < br_cntr_nr; i++) {
		u64 cntr = (br_cntr >> i * width) & mask;

		branch_br_cntr[off + i + base] += cntr;
		if (cntr == mask)
			branch_br_cntr[off + i + base] |= ANNOTATION__BR_CNTR_SATURATED_FLAG;
	}

	return 0;
}

static int symbol__account_cycles(u64 addr, u64 start, struct symbol *sym,
				  unsigned cycles, struct evsel *evsel,
				  u64 br_cntr)
{
	struct annotated_branch *branch;
	unsigned offset;
	int ret;

	if (sym == NULL)
		return 0;
	branch = symbol__find_branch_hist(sym, evsel->evlist->nr_br_cntr);
	if (!branch)
		return -ENOMEM;
	if (addr < sym->start || addr >= sym->end)
		return -ERANGE;

	if (start) {
		if (start < sym->start || start >= sym->end)
			return -ERANGE;
		if (start >= addr)
			start = 0;
	}
	offset = addr - sym->start;
	ret = __symbol__account_cycles(branch->cycles_hist,
					start ? start - sym->start : 0,
					offset, cycles,
					!!start);

	if (ret)
		return ret;

	return symbol__account_br_cntr(branch, evsel, offset, br_cntr);
}

int addr_map_symbol__account_cycles(struct addr_map_symbol *ams,
				    struct addr_map_symbol *start,
				    unsigned cycles,
				    struct evsel *evsel,
				    u64 br_cntr)
{
	u64 saddr = 0;
	int err;

	if (!cycles)
		return 0;

	/*
	 * Only set start when IPC can be computed. We can only
	 * compute it when the basic block is completely in a single
	 * function.
	 * Special case the case when the jump is elsewhere, but
	 * it starts on the function start.
	 */
	if (start &&
		(start->ms.sym == ams->ms.sym ||
		 (ams->ms.sym &&
		  start->addr == ams->ms.sym->start + map__start(ams->ms.map))))
		saddr = start->al_addr;
	if (saddr == 0)
		pr_debug2("BB with bad start: addr %"PRIx64" start %"PRIx64" sym %"PRIx64" saddr %"PRIx64"\n",
			ams->addr,
			start ? start->addr : 0,
			ams->ms.sym ? ams->ms.sym->start + map__start(ams->ms.map) : 0,
			saddr);
	err = symbol__account_cycles(ams->al_addr, saddr, ams->ms.sym, cycles, evsel, br_cntr);
	if (err)
		pr_debug2("account_cycles failed %d\n", err);
	return err;
}

struct annotation_line *annotated_source__get_line(struct annotated_source *src,
						   s64 offset)
{
	struct annotation_line *al;

	list_for_each_entry(al, &src->source, node) {
		if (al->offset == offset)
			return al;
	}
	return NULL;
}

static unsigned annotation__count_insn(struct annotation *notes, u64 start, u64 end)
{
	struct annotation_line *al;
	unsigned n_insn = 0;

	al = annotated_source__get_line(notes->src, start);
	if (al == NULL)
		return 0;

	list_for_each_entry_from(al, &notes->src->source, node) {
		if (al->offset == -1)
			continue;
		if ((u64)al->offset > end)
			break;
		n_insn++;
	}
	return n_insn;
}

static void annotated_branch__delete(struct annotated_branch *branch)
{
	if (branch) {
		zfree(&branch->cycles_hist);
		free(branch->br_cntr);
		free(branch);
	}
}

static void annotation__count_and_fill(struct annotation *notes, u64 start, u64 end, struct cyc_hist *ch)
{
	unsigned n_insn;
	unsigned int cover_insn = 0;

	n_insn = annotation__count_insn(notes, start, end);
	if (n_insn && ch->num && ch->cycles) {
		struct annotation_line *al;
		struct annotated_branch *branch;
		float ipc = n_insn / ((double)ch->cycles / (double)ch->num);

		/* Hide data when there are too many overlaps. */
		if (ch->reset >= 0x7fff)
			return;

		al = annotated_source__get_line(notes->src, start);
		if (al == NULL)
			return;

		list_for_each_entry_from(al, &notes->src->source, node) {
			if (al->offset == -1)
				continue;
			if ((u64)al->offset > end)
				break;
			if (al->cycles && al->cycles->ipc == 0.0) {
				al->cycles->ipc = ipc;
				cover_insn++;
			}
		}

		branch = annotation__get_branch(notes);
		if (cover_insn && branch) {
			branch->hit_cycles += ch->cycles;
			branch->hit_insn += n_insn * ch->num;
			branch->cover_insn += cover_insn;
		}
	}
}

static int annotation__compute_ipc(struct annotation *notes, size_t size,
				   struct evsel *evsel)
{
	unsigned int br_cntr_nr = evsel->evlist->nr_br_cntr;
	int err = 0;
	s64 offset;

	if (!notes->branch || !notes->branch->cycles_hist)
		return 0;

	notes->branch->total_insn = annotation__count_insn(notes, 0, size - 1);
	notes->branch->hit_cycles = 0;
	notes->branch->hit_insn = 0;
	notes->branch->cover_insn = 0;

	annotation__lock(notes);
	for (offset = size - 1; offset >= 0; --offset) {
		struct cyc_hist *ch;

		ch = &notes->branch->cycles_hist[offset];
		if (ch && ch->cycles) {
			struct annotation_line *al;

			al = annotated_source__get_line(notes->src, offset);
			if (al && al->cycles == NULL) {
				al->cycles = zalloc(sizeof(*al->cycles));
				if (al->cycles == NULL) {
					err = ENOMEM;
					break;
				}
			}
			if (ch->have_start)
				annotation__count_and_fill(notes, ch->start, offset, ch);
			if (al && ch->num_aggr) {
				al->cycles->avg = ch->cycles_aggr / ch->num_aggr;
				al->cycles->max = ch->cycles_max;
				al->cycles->min = ch->cycles_min;
			}
			if (al && notes->branch->br_cntr) {
				if (!al->br_cntr) {
					al->br_cntr = calloc(br_cntr_nr, sizeof(u64));
					if (!al->br_cntr) {
						err = ENOMEM;
						break;
					}
				}
				al->num_aggr = ch->num_aggr;
				al->br_cntr_nr = br_cntr_nr;
				al->evsel = evsel;
				memcpy(al->br_cntr, &notes->branch->br_cntr[offset * br_cntr_nr],
				       br_cntr_nr * sizeof(u64));
			}
		}
	}

	if (err) {
		while (++offset < (s64)size) {
			struct cyc_hist *ch = &notes->branch->cycles_hist[offset];

			if (ch && ch->cycles) {
				struct annotation_line *al;

				al = annotated_source__get_line(notes->src, offset);
				if (al) {
					zfree(&al->cycles);
					zfree(&al->br_cntr);
				}
			}
		}
	}

	annotation__unlock(notes);
	return 0;
}

int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, struct perf_sample *sample,
				 struct evsel *evsel)
{
	return symbol__inc_addr_samples(&ams->ms, evsel, ams->al_addr, sample);
}

int hist_entry__inc_addr_samples(struct hist_entry *he, struct perf_sample *sample,
				 struct evsel *evsel, u64 ip)
{
	return symbol__inc_addr_samples(&he->ms, evsel, ip, sample);
}


void annotation__exit(struct annotation *notes)
{
	annotated_source__delete(notes->src);
	annotated_branch__delete(notes->branch);
}

static struct sharded_mutex *sharded_mutex;

static void annotation__init_sharded_mutex(void)
{
	/* As many mutexes as there are CPUs. */
	sharded_mutex = sharded_mutex__new(cpu__max_present_cpu().cpu);
}

static size_t annotation__hash(const struct annotation *notes)
{
	return (size_t)notes;
}

static struct mutex *annotation__get_mutex(const struct annotation *notes)
{
	static pthread_once_t once = PTHREAD_ONCE_INIT;

	pthread_once(&once, annotation__init_sharded_mutex);
	if (!sharded_mutex)
		return NULL;

	return sharded_mutex__get_mutex(sharded_mutex, annotation__hash(notes));
}

void annotation__lock(struct annotation *notes)
	NO_THREAD_SAFETY_ANALYSIS
{
	struct mutex *mutex = annotation__get_mutex(notes);

	if (mutex)
		mutex_lock(mutex);
}

void annotation__unlock(struct annotation *notes)
	NO_THREAD_SAFETY_ANALYSIS
{
	struct mutex *mutex = annotation__get_mutex(notes);

	if (mutex)
		mutex_unlock(mutex);
}

bool annotation__trylock(struct annotation *notes)
{
	struct mutex *mutex = annotation__get_mutex(notes);

	if (!mutex)
		return false;

	return mutex_trylock(mutex);
}

void annotation_line__add(struct annotation_line *al, struct list_head *head)
{
	list_add_tail(&al->node, head);
}

struct annotation_line *
annotation_line__next(struct annotation_line *pos, struct list_head *head)
{
	list_for_each_entry_continue(pos, head, node)
		if (pos->offset >= 0)
			return pos;

	return NULL;
}

static const char *annotate__address_color(struct block_range *br)
{
	double cov = block_range__coverage(br);

	if (cov >= 0) {
		/* mark red for >75% coverage */
		if (cov > 0.75)
			return PERF_COLOR_RED;

		/* mark dull for <1% coverage */
		if (cov < 0.01)
			return PERF_COLOR_NORMAL;
	}

	return PERF_COLOR_MAGENTA;
}

static const char *annotate__asm_color(struct block_range *br)
{
	double cov = block_range__coverage(br);

	if (cov >= 0) {
		/* mark dull for <1% coverage */
		if (cov < 0.01)
			return PERF_COLOR_NORMAL;
	}

	return PERF_COLOR_BLUE;
}

static void annotate__branch_printf(struct block_range *br, u64 addr)
{
	bool emit_comment = true;

	if (!br)
		return;

#if 1
	if (br->is_target && br->start == addr) {
		struct block_range *branch = br;
		double p;

		/*
		 * Find matching branch to our target.
		 */
		while (!branch->is_branch)
			branch = block_range__next(branch);

		p = 100 *(double)br->entry / branch->coverage;

		if (p > 0.1) {
			if (emit_comment) {
				emit_comment = false;
				printf("\t#");
			}

			/*
			 * The percentage of coverage joined at this target in relation
			 * to the next branch.
			 */
			printf(" +%.2f%%", p);
		}
	}
#endif
	if (br->is_branch && br->end == addr) {
		double p = 100*(double)br->taken / br->coverage;

		if (p > 0.1) {
			if (emit_comment) {
				emit_comment = false;
				printf("\t#");
			}

			/*
			 * The percentage of coverage leaving at this branch, and
			 * its prediction ratio.
			 */
			printf(" -%.2f%% (p:%.2f%%)", p, 100*(double)br->pred  / br->taken);
		}
	}
}

static int disasm_line__print(struct disasm_line *dl, u64 start, int addr_fmt_width)
{
	s64 offset = dl->al.offset;
	const u64 addr = start + offset;
	struct block_range *br;

	br = block_range__find(addr);
	color_fprintf(stdout, annotate__address_color(br), "  %*" PRIx64 ":", addr_fmt_width, addr);
	color_fprintf(stdout, annotate__asm_color(br), "%s", dl->al.line);
	annotate__branch_printf(br, addr);
	return 0;
}

static struct annotated_data_type *
__hist_entry__get_data_type(struct hist_entry *he, const struct arch *arch,
			    struct debuginfo *dbg, struct disasm_line *dl,
			    int *type_offset);

static bool needs_type_info(struct annotated_data_type *data_type)
{
	if (data_type == NULL || data_type == NO_TYPE)
		return false;

	if (verbose)
		return true;

	return (data_type != &stackop_type) && (data_type != &canary_type);
}

static int
annotation_line__print(struct annotation_line *al, struct annotation_print_data *apd,
		       struct annotation_options *opts, int printed,
		       struct annotation_line *queue)
{
	struct symbol *sym = apd->he->ms.sym;
	struct disasm_line *dl = container_of(al, struct disasm_line, al);
	struct annotation *notes = symbol__annotation(sym);
	static const char *prev_line;
	int max_lines = opts->max_lines;
	int percent_type = opts->percent_type;

	if (al->offset != -1) {
		double max_percent = 0.0;
		int i, nr_percent = 1;
		const char *color;

		for (i = 0; i < al->data_nr; i++) {
			double percent;

			percent = annotation_data__percent(&al->data[i],
							   percent_type);

			if (percent > max_percent)
				max_percent = percent;
		}

		if (al->data_nr > nr_percent)
			nr_percent = al->data_nr;

		if (max_percent < opts->min_pcnt)
			return -1;

		if (max_lines && printed >= max_lines)
			return 1;

		if (queue != NULL) {
			struct annotation_options queue_opts = {
				.max_lines = 1,
				.percent_type = percent_type,
			};

			list_for_each_entry_from(queue, &notes->src->source, node) {
				if (queue == al)
					break;
				annotation_line__print(queue, apd, &queue_opts,
						       /*printed=*/0, /*queue=*/NULL);
			}
		}

		color = get_percent_color(max_percent);

		for (i = 0; i < nr_percent; i++) {
			struct annotation_data *data = &al->data[i];
			double percent;

			percent = annotation_data__percent(data, percent_type);
			color = get_percent_color(percent);

			if (symbol_conf.show_total_period)
				color_fprintf(stdout, color, " %11" PRIu64,
					      data->he.period);
			else if (symbol_conf.show_nr_samples)
				color_fprintf(stdout, color, " %7" PRIu64,
					      data->he.nr_samples);
			else
				color_fprintf(stdout, color, " %7.2f", percent);
		}

		printf(" : ");

		disasm_line__print(dl, notes->src->start, apd->addr_fmt_width);

		if (opts->code_with_type && apd->dbg) {
			struct annotated_data_type *data_type;
			int offset = 0;

			data_type = __hist_entry__get_data_type(apd->he, apd->arch,
								apd->dbg, dl, &offset);
			if (needs_type_info(data_type)) {
				char buf[4096];

				printf("\t\t# data-type: %s",
				       data_type->self.type_name);

				if (data_type != &stackop_type &&
				    data_type != &canary_type)
					printf(" +%#x", offset);

				if (annotated_data_type__get_member_name(data_type,
									 buf,
									 sizeof(buf),
									 offset))
					printf(" (%s)", buf);
			}
		}

		/*
		 * Also color the filename and line if needed, with
		 * the same color than the percentage. Don't print it
		 * twice for close colored addr with the same filename:line
		 */
		if (al->path) {
			if (!prev_line || strcmp(prev_line, al->path)) {
				color_fprintf(stdout, color, " // %s", al->path);
				prev_line = al->path;
			}
		}

		printf("\n");
	} else if (max_lines && printed >= max_lines)
		return 1;
	else {
		int width = annotation__pcnt_width(notes);

		if (queue)
			return -1;

		if (!*al->line)
			printf(" %*s:\n", width, " ");
		else
			printf(" %*s: %-*d %s\n", width, " ", apd->addr_fmt_width,
			       al->line_nr, al->line);
	}

	return 0;
}

static void calc_percent(struct annotation *notes,
			 struct evsel *evsel,
			 struct annotation_data *data,
			 s64 offset, s64 end)
{
	struct hists *hists = evsel__hists(evsel);
	struct sym_hist *sym_hist = annotation__histogram(notes, evsel);
	unsigned int hits = 0;
	u64 period = 0;

	while (offset < end) {
		struct sym_hist_entry *entry;

		entry = annotated_source__hist_entry(notes->src, evsel, offset);
		if (entry) {
			hits   += entry->nr_samples;
			period += entry->period;
		}
		++offset;
	}

	if (sym_hist->nr_samples) {
		data->he.period     = period;
		data->he.nr_samples = hits;
		data->percent[PERCENT_HITS_LOCAL] = 100.0 * hits / sym_hist->nr_samples;
	}

	if (hists->stats.nr_non_filtered_samples)
		data->percent[PERCENT_HITS_GLOBAL] = 100.0 * hits / hists->stats.nr_non_filtered_samples;

	if (sym_hist->period)
		data->percent[PERCENT_PERIOD_LOCAL] = 100.0 * period / sym_hist->period;

	if (hists->stats.total_period)
		data->percent[PERCENT_PERIOD_GLOBAL] = 100.0 * period / hists->stats.total_period;
}

static void annotation__calc_percent(struct annotation *notes,
				     struct evsel *leader, s64 len)
{
	struct annotation_line *al, *next;
	struct evsel *evsel;

	list_for_each_entry(al, &notes->src->source, node) {
		s64 end;
		int i = 0;

		if (al->offset == -1)
			continue;

		next = annotation_line__next(al, &notes->src->source);
		end  = next ? next->offset : len;

		for_each_group_evsel(evsel, leader) {
			struct annotation_data *data;

			BUG_ON(i >= al->data_nr);

			if (symbol_conf.skip_empty &&
			    evsel__hists(evsel)->stats.nr_samples == 0)
				continue;

			data = &al->data[i++];

			calc_percent(notes, evsel, data, al->offset, end);
		}
	}
}

void symbol__calc_percent(struct symbol *sym, struct evsel *evsel)
{
	struct annotation *notes = symbol__annotation(sym);

	annotation__calc_percent(notes, evsel, symbol__size(sym));
}

int thread__get_arch(struct thread *thread, const struct arch **parch)
{
	const struct arch *arch;
	struct machine *machine;
	uint32_t e_flags;
	uint16_t e_machine;

	if (!thread) {
		*parch = NULL;
		return -1;
	}

	machine = maps__machine(thread__maps(thread));
	e_machine = thread__e_machine(thread, machine, &e_flags);
	arch = arch__find(e_machine, e_flags, machine->env ? machine->env->cpuid : NULL);
	if (arch == NULL) {
		pr_err("%s: unsupported arch %d\n", __func__, e_machine);
		return errno;
	}
	if (parch)
		*parch = arch;

	return 0;
}

int symbol__annotate(struct map_symbol *ms, struct evsel *evsel,
		     const struct arch **parch)
{
	struct symbol *sym = ms->sym;
	struct annotation *notes = symbol__annotation(sym);
	struct annotate_args args = {
		.options	= &annotate_opts,
	};
	const struct arch *arch = NULL;
	int err, nr;

	err = thread__get_arch(ms->thread, &arch);
	if (err)
		return err;

	if (parch)
		*parch = arch;

	if (notes->src && !list_empty(&notes->src->source))
		return 0;

	args.arch = arch;
	args.ms = ms;

	if (notes->src == NULL) {
		notes->src = annotated_source__new();
		if (notes->src == NULL)
			return -1;
	}

	nr = 0;
	if (evsel__is_group_event(evsel)) {
		struct evsel *pos;

		for_each_group_evsel(pos, evsel) {
			if (symbol_conf.skip_empty &&
			    evsel__hists(pos)->stats.nr_samples == 0)
				continue;
			nr++;
		}
	}
	notes->src->nr_events = nr ? nr : 1;

	if (annotate_opts.full_addr)
		notes->src->start = map__objdump_2mem(ms->map, ms->sym->start);
	else
		notes->src->start = map__rip_2objdump(ms->map, ms->sym->start);

	return symbol__disassemble(sym, &args);
}

static void insert_source_line(struct rb_root *root, struct annotation_line *al)
{
	struct annotation_line *iter;
	struct rb_node **p = &root->rb_node;
	struct rb_node *parent = NULL;
	unsigned int percent_type = annotate_opts.percent_type;
	int i, ret;

	while (*p != NULL) {
		parent = *p;
		iter = rb_entry(parent, struct annotation_line, rb_node);

		ret = strcmp(iter->path, al->path);
		if (ret == 0) {
			for (i = 0; i < al->data_nr; i++) {
				iter->data[i].percent_sum += annotation_data__percent(&al->data[i],
										      percent_type);
			}
			return;
		}

		if (ret < 0)
			p = &(*p)->rb_left;
		else
			p = &(*p)->rb_right;
	}

	for (i = 0; i < al->data_nr; i++) {
		al->data[i].percent_sum = annotation_data__percent(&al->data[i],
								   percent_type);
	}

	rb_link_node(&al->rb_node, parent, p);
	rb_insert_color(&al->rb_node, root);
}

static int cmp_source_line(struct annotation_line *a, struct annotation_line *b)
{
	int i;

	for (i = 0; i < a->data_nr; i++) {
		if (a->data[i].percent_sum == b->data[i].percent_sum)
			continue;
		return a->data[i].percent_sum > b->data[i].percent_sum;
	}

	return 0;
}

static void __resort_source_line(struct rb_root *root, struct annotation_line *al)
{
	struct annotation_line *iter;
	struct rb_node **p = &root->rb_node;
	struct rb_node *parent = NULL;

	while (*p != NULL) {
		parent = *p;
		iter = rb_entry(parent, struct annotation_line, rb_node);

		if (cmp_source_line(al, iter))
			p = &(*p)->rb_left;
		else
			p = &(*p)->rb_right;
	}

	rb_link_node(&al->rb_node, parent, p);
	rb_insert_color(&al->rb_node, root);
}

static void resort_source_line(struct rb_root *dest_root, struct rb_root *src_root)
{
	struct annotation_line *al;
	struct rb_node *node;

	node = rb_first(src_root);
	while (node) {
		struct rb_node *next;

		al = rb_entry(node, struct annotation_line, rb_node);
		next = rb_next(node);
		rb_erase(node, src_root);

		__resort_source_line(dest_root, al);
		node = next;
	}
}

static void print_summary(struct rb_root *root, const char *filename)
{
	struct annotation_line *al;
	struct rb_node *node;

	printf("\nSorted summary for file %s\n", filename);
	printf("----------------------------------------------\n\n");

	if (RB_EMPTY_ROOT(root)) {
		printf(" Nothing higher than %1.1f%%\n", MIN_GREEN);
		return;
	}

	node = rb_first(root);
	while (node) {
		double percent, percent_max = 0.0;
		const char *color;
		char *path;
		int i;

		al = rb_entry(node, struct annotation_line, rb_node);
		for (i = 0; i < al->data_nr; i++) {
			percent = al->data[i].percent_sum;
			color = get_percent_color(percent);
			color_fprintf(stdout, color, " %7.2f", percent);

			if (percent > percent_max)
				percent_max = percent;
		}

		path = al->path;
		color = get_percent_color(percent_max);
		color_fprintf(stdout, color, " %s\n", path);

		node = rb_next(node);
	}
}

static void symbol__annotate_hits(struct symbol *sym, struct evsel *evsel)
{
	struct annotation *notes = symbol__annotation(sym);
	struct sym_hist *h = annotation__histogram(notes, evsel);
	u64 len = symbol__size(sym), offset;

	for (offset = 0; offset < len; ++offset) {
		struct sym_hist_entry *entry;

		entry = annotated_source__hist_entry(notes->src, evsel, offset);
		if (entry && entry->nr_samples != 0)
			printf("%*" PRIx64 ": %" PRIu64 "\n", BITS_PER_LONG / 2,
			       sym->start + offset, entry->nr_samples);
	}
	printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->nr_samples", h->nr_samples);
}

static int annotated_source__addr_fmt_width(struct list_head *lines, u64 start)
{
	char bf[32];
	struct annotation_line *line;

	list_for_each_entry_reverse(line, lines, node) {
		if (line->offset != -1)
			return scnprintf(bf, sizeof(bf), "%" PRIx64, start + line->offset);
	}

	return 0;
}

int hist_entry__annotate_printf(struct hist_entry *he, struct evsel *evsel)
{
	struct map_symbol *ms = &he->ms;
	struct map *map = ms->map;
	struct symbol *sym = ms->sym;
	struct dso *dso = map__dso(map);
	char *filename;
	const char *d_filename;
	const char *evsel_name = evsel__name(evsel);
	struct annotation *notes = symbol__annotation(sym);
	struct sym_hist *h = annotation__histogram(notes, evsel);
	struct annotation_line *pos, *queue = NULL;
	struct annotation_options *opts = &annotate_opts;
	struct annotation_print_data apd = {
		.he = he,
		.evsel = evsel,
	};
	int printed = 2, queue_len = 0;
	int more = 0;
	bool context = opts->context;
	int width = annotation__pcnt_width(notes);
	int graph_dotted_len;
	char buf[512];

	filename = strdup(dso__long_name(dso));
	if (!filename)
		return -ENOMEM;

	if (opts->full_path)
		d_filename = filename;
	else
		d_filename = basename(filename);

	if (evsel__is_group_event(evsel)) {
		evsel__group_desc(evsel, buf, sizeof(buf));
		evsel_name = buf;
	}

	graph_dotted_len = printf(" %-*.*s|	Source code & Disassembly of %s for %s (%" PRIu64 " samples, "
				  "percent: %s)\n",
				  width, width, symbol_conf.show_total_period ? "Period" :
				  symbol_conf.show_nr_samples ? "Samples" : "Percent",
				  d_filename, evsel_name, h->nr_samples,
				  percent_type_str(opts->percent_type));

	printf("%-*.*s----\n",
	       graph_dotted_len, graph_dotted_len, graph_dotted_line);

	if (verbose > 0)
		symbol__annotate_hits(sym, evsel);

	apd.addr_fmt_width = annotated_source__addr_fmt_width(&notes->src->source,
							      notes->src->start);
	thread__get_arch(ms->thread, &apd.arch);
	apd.dbg = dso__debuginfo(dso);

	list_for_each_entry(pos, &notes->src->source, node) {
		int err;

		if (context && queue == NULL) {
			queue = pos;
			queue_len = 0;
		}

		err = annotation_line__print(pos, &apd, opts, printed, queue);

		switch (err) {
		case 0:
			++printed;
			if (context) {
				printed += queue_len;
				queue = NULL;
				queue_len = 0;
			}
			break;
		case 1:
			/* filtered by max_lines */
			++more;
			break;
		case -1:
		default:
			/*
			 * Filtered by min_pcnt or non IP lines when
			 * context != 0
			 */
			if (!context)
				break;
			if (queue_len == context)
				queue = list_entry(queue->node.next, typeof(*queue), node);
			else
				++queue_len;
			break;
		}
	}

	debuginfo__delete(apd.dbg);
	free(filename);

	return more;
}

static void FILE__set_percent_color(void *fp __maybe_unused,
				    double percent __maybe_unused,
				    bool current __maybe_unused)
{
}

static int FILE__set_jumps_percent_color(void *fp __maybe_unused,
					 int nr __maybe_unused, bool current __maybe_unused)
{
	return 0;
}

static int FILE__set_color(void *fp __maybe_unused, int color __maybe_unused)
{
	return 0;
}

static void FILE__printf(void *fp, const char *fmt, ...)
{
	va_list args;

	va_start(args, fmt);
	vfprintf(fp, fmt, args);
	va_end(args);
}

static void FILE__write_graph(void *fp, int graph)
{
	const char *s;
	switch (graph) {

	case DARROW_CHAR: s = "↓"; break;
	case UARROW_CHAR: s = "↑"; break;
	case LARROW_CHAR: s = "←"; break;
	case RARROW_CHAR: s = "→"; break;
	default:		s = "?"; break;
	}

	fputs(s, fp);
}

static int symbol__annotate_fprintf2(struct symbol *sym, FILE *fp,
				     struct annotation_print_data *apd)
{
	struct annotation *notes = symbol__annotation(sym);
	struct annotation_write_ops wops = {
		.first_line		 = true,
		.obj			 = fp,
		.set_color		 = FILE__set_color,
		.set_percent_color	 = FILE__set_percent_color,
		.set_jumps_percent_color = FILE__set_jumps_percent_color,
		.printf			 = FILE__printf,
		.write_graph		 = FILE__write_graph,
	};
	struct annotation_line *al;

	if (annotate_opts.code_with_type) {
		thread__get_arch(apd->he->ms.thread, &apd->arch);
		apd->dbg = dso__debuginfo(map__dso(apd->he->ms.map));
	}

	list_for_each_entry(al, &notes->src->source, node) {
		if (annotation_line__filter(al))
			continue;
		annotation_line__write(al, notes, &wops, apd);
		fputc('\n', fp);
		wops.first_line = false;
	}

	if (annotate_opts.code_with_type)
		debuginfo__delete(apd->dbg);

	return 0;
}

int map_symbol__annotation_dump(struct map_symbol *ms, struct evsel *evsel,
				struct hist_entry *he)
{
	const char *ev_name = evsel__name(evsel);
	char buf[1024];
	char *filename;
	int err = -1;
	FILE *fp;
	struct annotation_print_data apd = {
		.he = he,
		.evsel = evsel,
	};

	if (asprintf(&filename, "%s.annotation", ms->sym->name) < 0)
		return -1;

	fp = fopen(filename, "w");
	if (fp == NULL)
		goto out_free_filename;

	if (evsel__is_group_event(evsel)) {
		evsel__group_desc(evsel, buf, sizeof(buf));
		ev_name = buf;
	}

	fprintf(fp, "%s() %s\nEvent: %s\n\n",
		ms->sym->name, dso__long_name(map__dso(ms->map)), ev_name);
	symbol__annotate_fprintf2(ms->sym, fp, &apd);

	fclose(fp);
	err = 0;
out_free_filename:
	free(filename);
	return err;
}

void symbol__annotate_zero_histogram(struct symbol *sym, struct evsel *evsel)
{
	struct annotation *notes = symbol__annotation(sym);
	struct sym_hist *h = annotation__histogram(notes, evsel);

	memset(h, 0, sizeof(*notes->src->histograms) * notes->src->nr_histograms);
}

void symbol__annotate_decay_histogram(struct symbol *sym, struct evsel *evsel)
{
	struct annotation *notes = symbol__annotation(sym);
	struct sym_hist *h = annotation__histogram(notes, evsel);
	struct annotation_line *al;

	h->nr_samples = 0;
	list_for_each_entry(al, &notes->src->source, node) {
		struct sym_hist_entry *entry;

		if (al->offset == -1)
			continue;

		entry = annotated_source__hist_entry(notes->src, evsel, al->offset);
		if (entry == NULL)
			continue;

		entry->nr_samples = entry->nr_samples * 7 / 8;
		h->nr_samples += entry->nr_samples;
	}
}

void annotated_source__purge(struct annotated_source *as)
{
	struct annotation_line *al, *n;

	list_for_each_entry_safe(al, n, &as->source, node) {
		list_del_init(&al->node);
		disasm_line__free(disasm_line(al));
	}
	as->tried_source = false;
}

static size_t disasm_line__fprintf(struct disasm_line *dl, FILE *fp)
{
	size_t printed;

	if (dl->al.offset == -1)
		return fprintf(fp, "%s\n", dl->al.line);

	printed = fprintf(fp, "%#" PRIx64 " %s", dl->al.offset, dl->ins.name);

	if (dl->ops.raw[0] != '\0') {
		printed += fprintf(fp, "%.*s %s\n", 6 - (int)printed, " ",
				   dl->ops.raw);
	}

	return printed + fprintf(fp, "\n");
}

size_t disasm__fprintf(struct list_head *head, FILE *fp)
{
	struct disasm_line *pos;
	size_t printed = 0;

	list_for_each_entry(pos, head, al.node)
		printed += disasm_line__fprintf(pos, fp);

	return printed;
}

bool disasm_line__is_valid_local_jump(struct disasm_line *dl, struct symbol *sym)
{
	if (!dl || !dl->ins.ops || !ins__is_jump(&dl->ins) ||
	    !disasm_line__has_local_offset(dl) || dl->ops.target.offset < 0 ||
	    dl->ops.target.offset >= (s64)symbol__size(sym))
		return false;

	return true;
}

static void
annotation__mark_jump_targets(struct annotation *notes, struct symbol *sym)
{
	struct annotation_line *al;

	/* PLT symbols contain external offsets */
	if (strstr(sym->name, "@plt"))
		return;

	list_for_each_entry(al, &notes->src->source, node) {
		struct disasm_line *dl;
		struct annotation_line *target;

		dl = disasm_line(al);

		if (!disasm_line__is_valid_local_jump(dl, sym))
			continue;

		target = annotated_source__get_line(notes->src,
						    dl->ops.target.offset);
		/*
		 * FIXME: Oops, no jump target? Buggy disassembler? Or do we
		 * have to adjust to the previous offset?
		 */
		if (target == NULL)
			continue;

		if (++target->jump_sources > notes->src->max_jump_sources)
			notes->src->max_jump_sources = target->jump_sources;
	}
}

static void annotation__set_index(struct annotation *notes)
{
	struct annotation_line *al;
	struct annotated_source *src = notes->src;

	src->widths.max_line_len = 0;
	src->nr_entries = 0;
	src->nr_asm_entries = 0;

	list_for_each_entry(al, &src->source, node) {
		size_t line_len = strlen(al->line);

		if (src->widths.max_line_len < line_len)
			src->widths.max_line_len = line_len;
		al->idx = src->nr_entries++;
		if (al->offset != -1)
			al->idx_asm = src->nr_asm_entries++;
		else
			al->idx_asm = -1;
	}
}

static inline int width_jumps(int n)
{
	if (n >= 100)
		return 5;
	if (n / 10)
		return 2;
	return 1;
}

static int annotation__max_ins_name(struct annotation *notes)
{
	int max_name = 0, len;
	struct annotation_line *al;

        list_for_each_entry(al, &notes->src->source, node) {
		if (al->offset == -1)
			continue;

		len = strlen(disasm_line(al)->ins.name);
		if (max_name < len)
			max_name = len;
	}

	return max_name;
}

static void
annotation__init_column_widths(struct annotation *notes, struct symbol *sym)
{
	notes->src->widths.addr = notes->src->widths.target =
		notes->src->widths.min_addr = hex_width(symbol__size(sym));
	notes->src->widths.max_addr = hex_width(sym->end);
	notes->src->widths.jumps = width_jumps(notes->src->max_jump_sources);
	notes->src->widths.max_ins_name = annotation__max_ins_name(notes);
}

void annotation__update_column_widths(struct annotation *notes)
{
	if (annotate_opts.use_offset)
		notes->src->widths.target = notes->src->widths.min_addr;
	else if (annotate_opts.full_addr)
		notes->src->widths.target = BITS_PER_LONG / 4;
	else
		notes->src->widths.target = notes->src->widths.max_addr;

	notes->src->widths.addr = notes->src->widths.target;

	if (annotate_opts.show_nr_jumps)
		notes->src->widths.addr += notes->src->widths.jumps + 1;
}

void annotation__toggle_full_addr(struct annotation *notes, struct map_symbol *ms)
{
	annotate_opts.full_addr = !annotate_opts.full_addr;

	if (annotate_opts.full_addr)
		notes->src->start = map__objdump_2mem(ms->map, ms->sym->start);
	else
		notes->src->start = map__rip_2objdump(ms->map, ms->sym->start);

	annotation__update_column_widths(notes);
}

static void annotation__calc_lines(struct annotation *notes, struct map_symbol *ms,
				   struct rb_root *root)
{
	struct annotation_line *al;
	struct rb_root tmp_root = RB_ROOT;

	list_for_each_entry(al, &notes->src->source, node) {
		double percent_max = 0.0;
		u64 addr;
		int i;

		for (i = 0; i < al->data_nr; i++) {
			double percent;

			percent = annotation_data__percent(&al->data[i],
							   annotate_opts.percent_type);

			if (percent > percent_max)
				percent_max = percent;
		}

		if (percent_max <= 0.5)
			continue;

		addr = map__rip_2objdump(ms->map, ms->sym->start);
		al->path = get_srcline(map__dso(ms->map), addr + al->offset, NULL,
				       false, true, ms->sym->start + al->offset);
		insert_source_line(&tmp_root, al);
	}

	resort_source_line(root, &tmp_root);
}

static void symbol__calc_lines(struct map_symbol *ms, struct rb_root *root)
{
	struct annotation *notes = symbol__annotation(ms->sym);

	annotation__calc_lines(notes, ms, root);
}

int hist_entry__tty_annotate2(struct hist_entry *he, struct evsel *evsel)
{
	struct map_symbol *ms = &he->ms;
	struct dso *dso = map__dso(ms->map);
	struct symbol *sym = ms->sym;
	struct rb_root source_line = RB_ROOT;
	struct hists *hists = evsel__hists(evsel);
	struct annotation_print_data apd = {
		.he = he,
		.evsel = evsel,
	};
	char buf[1024];
	int err;

	err = symbol__annotate2(ms, evsel, NULL);
	if (err) {
		char msg[BUFSIZ];

		dso__set_annotate_warned(dso);
		symbol__strerror_disassemble(ms, err, msg, sizeof(msg));
		ui__error("Couldn't annotate %s:\n%s", sym->name, msg);
		return -1;
	}

	if (annotate_opts.print_lines) {
		srcline_full_filename = annotate_opts.full_path;
		symbol__calc_lines(ms, &source_line);
		print_summary(&source_line, dso__long_name(dso));
	}

	hists__scnprintf_title(hists, buf, sizeof(buf));
	fprintf(stdout, "%s, [percent: %s]\n%s() %s\n",
		buf, percent_type_str(annotate_opts.percent_type), sym->name, dso__long_name(dso));
	symbol__annotate_fprintf2(sym, stdout, &apd);

	annotated_source__purge(symbol__annotation(sym)->src);

	return 0;
}

int hist_entry__tty_annotate(struct hist_entry *he, struct evsel *evsel)
{
	struct map_symbol *ms = &he->ms;
	struct dso *dso = map__dso(ms->map);
	struct symbol *sym = ms->sym;
	struct rb_root source_line = RB_ROOT;
	int err;

	err = symbol__annotate(ms, evsel, NULL);
	if (err) {
		char msg[BUFSIZ];

		dso__set_annotate_warned(dso);
		symbol__strerror_disassemble(ms, err, msg, sizeof(msg));
		ui__error("Couldn't annotate %s:\n%s", sym->name, msg);
		return -1;
	}

	symbol__calc_percent(sym, evsel);

	if (annotate_opts.print_lines) {
		srcline_full_filename = annotate_opts.full_path;
		symbol__calc_lines(ms, &source_line);
		print_summary(&source_line, dso__long_name(dso));
	}

	hist_entry__annotate_printf(he, evsel);

	annotated_source__purge(symbol__annotation(sym)->src);

	return 0;
}

bool ui__has_annotation(void)
{
	return use_browser == 1 && perf_hpp_list.sym;
}


static double annotation_line__max_percent(struct annotation_line *al,
					   unsigned int percent_type)
{
	double percent_max = 0.0;
	int i;

	for (i = 0; i < al->data_nr; i++) {
		double percent;

		percent = annotation_data__percent(&al->data[i],
						   percent_type);

		if (percent > percent_max)
			percent_max = percent;
	}

	return percent_max;
}

static int disasm_line__write(struct disasm_line *dl, struct annotation *notes,
			       void *obj, char *bf, size_t size,
			       void (*obj__printf)(void *obj, const char *fmt, ...),
			       void (*obj__write_graph)(void *obj, int graph))
{
	if (dl->ins.ops && dl->ins.ops->scnprintf) {
		if (ins__is_jump(&dl->ins)) {
			bool fwd;

			if (dl->ops.target.outside)
				goto call_like;
			fwd = dl->ops.target.offset > dl->al.offset;
			obj__write_graph(obj, fwd ? DARROW_CHAR : UARROW_CHAR);
			obj__printf(obj, " ");
		} else if (ins__is_call(&dl->ins)) {
call_like:
			obj__write_graph(obj, RARROW_CHAR);
			obj__printf(obj, " ");
		} else if (ins__is_ret(&dl->ins)) {
			obj__write_graph(obj, LARROW_CHAR);
			obj__printf(obj, " ");
		} else {
			obj__printf(obj, "  ");
		}
	} else {
		obj__printf(obj, "  ");
	}

	return disasm_line__scnprintf(dl, bf, size, !annotate_opts.use_offset,
				      notes->src->widths.max_ins_name) + 2;
}

static void ipc_coverage_string(char *bf, int size, struct annotation *notes)
{
	double ipc = 0.0, coverage = 0.0;
	struct annotated_branch *branch = annotation__get_branch(notes);

	if (branch && branch->hit_cycles)
		ipc = branch->hit_insn / ((double)branch->hit_cycles);

	if (branch && branch->total_insn) {
		coverage = branch->cover_insn * 100.0 /
			((double)branch->total_insn);
	}

	scnprintf(bf, size, "(Average IPC: %.2f, IPC Coverage: %.1f%%)",
		  ipc, coverage);
}

int annotation_br_cntr_abbr_list(char **str, struct evsel *evsel, bool header)
{
	struct evsel *pos;
	struct strbuf sb;

	if (evsel->evlist->nr_br_cntr <= 0)
		return -ENOTSUP;

	strbuf_init(&sb, /*hint=*/ 0);

	if (header && strbuf_addf(&sb, "# Branch counter abbr list:\n"))
		goto err;

	evlist__for_each_entry(evsel->evlist, pos) {
		if (!(pos->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_COUNTERS))
			continue;
		if (header && strbuf_addf(&sb, "#"))
			goto err;

		if (strbuf_addf(&sb, " %s = %s\n", pos->name, pos->abbr_name))
			goto err;
	}

	if (header && strbuf_addf(&sb, "#"))
		goto err;
	if (strbuf_addf(&sb, " '-' No event occurs\n"))
		goto err;

	if (header && strbuf_addf(&sb, "#"))
		goto err;
	if (strbuf_addf(&sb, " '+' Event occurrences may be lost due to branch counter saturated\n"))
		goto err;

	*str = strbuf_detach(&sb, NULL);

	return 0;
err:
	strbuf_release(&sb);
	return -ENOMEM;
}

/* Assume the branch counter saturated at 3 */
#define ANNOTATION_BR_CNTR_SATURATION		3

int annotation_br_cntr_entry(char **str, int br_cntr_nr,
			     u64 *br_cntr, int num_aggr,
			     struct evsel *evsel)
{
	struct evsel *pos = evsel ? evlist__first(evsel->evlist) : NULL;
	bool saturated = false;
	int i, j, avg, used;
	struct strbuf sb;

	strbuf_init(&sb, /*hint=*/ 0);
	for (i = 0; i < br_cntr_nr; i++) {
		used = 0;
		avg = ceil((double)(br_cntr[i] & ~ANNOTATION__BR_CNTR_SATURATED_FLAG) /
			   (double)num_aggr);

		/*
		 * A histogram with the abbr name is displayed by default.
		 * With -v, the exact number of branch counter is displayed.
		 */
		if (verbose) {
			evlist__for_each_entry_from(evsel->evlist, pos) {
				if ((pos->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_COUNTERS) &&
				    (pos->br_cntr_idx == i))
				break;
			}
			if (strbuf_addstr(&sb, pos->abbr_name))
				goto err;

			if (!br_cntr[i]) {
				if (strbuf_addstr(&sb, "=-"))
					goto err;
			} else {
				if (strbuf_addf(&sb, "=%d", avg))
					goto err;
			}
			if (br_cntr[i] & ANNOTATION__BR_CNTR_SATURATED_FLAG) {
				if (strbuf_addch(&sb, '+'))
					goto err;
			} else {
				if (strbuf_addch(&sb, ' '))
					goto err;
			}

			if ((i < br_cntr_nr - 1) && strbuf_addch(&sb, ','))
				goto err;
			continue;
		}

		if (strbuf_addch(&sb, '|'))
			goto err;

		if (!br_cntr[i]) {
			if (strbuf_addch(&sb, '-'))
				goto err;
			used++;
		} else {
			evlist__for_each_entry_from(evsel->evlist, pos) {
				if ((pos->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_COUNTERS) &&
				    (pos->br_cntr_idx == i))
					break;
			}
			if (br_cntr[i] & ANNOTATION__BR_CNTR_SATURATED_FLAG)
				saturated = true;

			for (j = 0; j < avg; j++, used++) {
				/* Print + if the number of logged events > 3 */
				if (j >= ANNOTATION_BR_CNTR_SATURATION) {
					saturated = true;
					break;
				}
				if (strbuf_addstr(&sb, pos->abbr_name))
					goto err;
			}

			if (saturated) {
				if (strbuf_addch(&sb, '+'))
					goto err;
				used++;
			}
			pos = list_next_entry(pos, core.node);
		}

		for (j = used; j < ANNOTATION_BR_CNTR_SATURATION + 1; j++) {
			if (strbuf_addch(&sb, ' '))
				goto err;
		}
	}

	if (!verbose && strbuf_addch(&sb, br_cntr_nr ? '|' : ' '))
		goto err;

	*str = strbuf_detach(&sb, NULL);

	return 0;
err:
	strbuf_release(&sb);
	return -ENOMEM;
}

struct type_hash_entry {
	struct annotated_data_type *type;
	int offset;
};

static int disasm_line__snprint_type_info(struct disasm_line *dl,
					  char *buf, int len,
					  struct annotation_print_data *apd)
{
	struct annotated_data_type *data_type = NULL;
	struct type_hash_entry *entry = NULL;
	char member[256];
	int offset = 0;
	int printed;

	scnprintf(buf, len, " ");

	if (!annotate_opts.code_with_type || apd->dbg == NULL)
		return 1;

	if (apd->type_hash) {
		hashmap__find(apd->type_hash, dl->al.offset, &entry);
		if (entry != NULL) {
			data_type = entry->type;
			offset = entry->offset;
		}
	}

	if (data_type == NULL)
		data_type = __hist_entry__get_data_type(apd->he, apd->arch, apd->dbg, dl, &offset);

	if (apd->type_hash && entry == NULL) {
		entry = malloc(sizeof(*entry));
		if (entry != NULL) {
			entry->type = data_type;
			entry->offset = offset;
			hashmap__add(apd->type_hash, dl->al.offset, entry);
		}
	}

	if (!needs_type_info(data_type))
		return 1;

	printed = scnprintf(buf, len, "\t\t# data-type: %s", data_type->self.type_name);

	if (data_type != &stackop_type && data_type != &canary_type && len > printed)
		printed += scnprintf(buf + printed, len - printed, " +%#x", offset);

	if (annotated_data_type__get_member_name(data_type, member, sizeof(member), offset) &&
	    len > printed) {
		printed += scnprintf(buf + printed, len - printed, " (%s)", member);
	}
	return printed;
}

void annotation_line__write(struct annotation_line *al, struct annotation *notes,
			    const struct annotation_write_ops *wops,
			    struct annotation_print_data *apd)
{
	bool current_entry = wops->current_entry;
	bool change_color = wops->change_color;
	double percent_max = annotation_line__max_percent(al, annotate_opts.percent_type);
	int width = wops->width;
	int pcnt_width = annotation__pcnt_width(notes);
	int cycles_width = annotation__cycles_width(notes);
	bool show_title = false;
	char bf[256];
	int printed;
	void *obj = wops->obj;
	int  (*obj__set_color)(void *obj, int color) = wops->set_color;
	void (*obj__set_percent_color)(void *obj, double percent, bool current) = wops->set_percent_color;
	int  (*obj__set_jumps_percent_color)(void *obj, int nr, bool current) = wops->set_jumps_percent_color;
	void (*obj__printf)(void *obj, const char *fmt, ...) = wops->printf;
	void (*obj__write_graph)(void *obj, int graph) = wops->write_graph;

	if (wops->first_line && (al->offset == -1 || percent_max == 0.0)) {
		if (notes->branch && al->cycles) {
			if (al->cycles->ipc == 0.0 && al->cycles->avg == 0)
				show_title = true;
		} else
			show_title = true;
	}

	if (al->offset != -1 && percent_max != 0.0) {
		int i;

		for (i = 0; i < al->data_nr; i++) {
			double percent;

			percent = annotation_data__percent(&al->data[i],
							   annotate_opts.percent_type);

			obj__set_percent_color(obj, percent, current_entry);
			if (symbol_conf.show_total_period) {
				obj__printf(obj, "%11" PRIu64 " ", al->data[i].he.period);
			} else if (symbol_conf.show_nr_samples) {
				obj__printf(obj, "%7" PRIu64 " ",
						   al->data[i].he.nr_samples);
			} else {
				obj__printf(obj, "%7.2f ", percent);
			}
		}
	} else {
		obj__set_percent_color(obj, 0, current_entry);

		if (!show_title)
			obj__printf(obj, "%-*s", pcnt_width, " ");
		else {
			obj__printf(obj, "%-*s", pcnt_width,
					   symbol_conf.show_total_period ? "Period" :
					   symbol_conf.show_nr_samples ? "Samples" : "Percent");
		}
	}
	width -= pcnt_width;

	if (notes->branch) {
		if (al->cycles && al->cycles->ipc)
			obj__printf(obj, "%*.2f ", ANNOTATION__IPC_WIDTH - 1, al->cycles->ipc);
		else if (!show_title)
			obj__printf(obj, "%*s", ANNOTATION__IPC_WIDTH, " ");
		else
			obj__printf(obj, "%*s ", ANNOTATION__IPC_WIDTH - 1, "IPC");

		if (!annotate_opts.show_minmax_cycle) {
			if (al->cycles && al->cycles->avg)
				obj__printf(obj, "%*" PRIu64 " ",
					   ANNOTATION__CYCLES_WIDTH - 1, al->cycles->avg);
			else if (!show_title)
				obj__printf(obj, "%*s",
					    ANNOTATION__CYCLES_WIDTH, " ");
			else
				obj__printf(obj, "%*s ",
					    ANNOTATION__CYCLES_WIDTH - 1,
					    "Cycle");
		} else {
			if (al->cycles) {
				char str[32];

				scnprintf(str, sizeof(str),
					"%" PRIu64 "(%" PRIu64 "/%" PRIu64 ")",
					al->cycles->avg, al->cycles->min,
					al->cycles->max);

				obj__printf(obj, "%*s ",
					    ANNOTATION__MINMAX_CYCLES_WIDTH - 1,
					    str);
			} else if (!show_title)
				obj__printf(obj, "%*s",
					    ANNOTATION__MINMAX_CYCLES_WIDTH,
					    " ");
			else
				obj__printf(obj, "%*s ",
					    ANNOTATION__MINMAX_CYCLES_WIDTH - 1,
					    "Cycle(min/max)");
		}

		if (annotate_opts.show_br_cntr) {
			if (show_title) {
				obj__printf(obj, "%*s ",
					    ANNOTATION__BR_CNTR_WIDTH,
					    "Branch Counter");
			} else {
				char *buf;

				if (!annotation_br_cntr_entry(&buf, al->br_cntr_nr, al->br_cntr,
							      al->num_aggr, al->evsel)) {
					obj__printf(obj, "%*s ", ANNOTATION__BR_CNTR_WIDTH, buf);
					free(buf);
				}
			}
		}

		if (show_title && !*al->line) {
			ipc_coverage_string(bf, sizeof(bf), notes);
			obj__printf(obj, "%*s", ANNOTATION__AVG_IPC_WIDTH, bf);
		}
	}
	width -= cycles_width;

	obj__printf(obj, " ");
	width -= 1;

	if (!*al->line)
		obj__printf(obj, "%-*s", width, " ");
	else if (al->offset == -1) {
		if (al->line_nr && annotate_opts.show_linenr)
			printed = scnprintf(bf, sizeof(bf), "%-*d ",
					    notes->src->widths.addr + 1, al->line_nr);
		else
			printed = scnprintf(bf, sizeof(bf), "%-*s  ",
					    notes->src->widths.addr, " ");
		obj__printf(obj, bf);
		width -= printed;
		obj__printf(obj, "%-*s", width, al->line);
	} else {
		u64 addr = al->offset;
		int color = -1;

		if (!annotate_opts.use_offset)
			addr += notes->src->start;

		if (!annotate_opts.use_offset) {
			printed = scnprintf(bf, sizeof(bf), "%" PRIx64 ": ", addr);
		} else {
			if (al->jump_sources &&
			    annotate_opts.offset_level >= ANNOTATION__OFFSET_JUMP_TARGETS) {
				if (annotate_opts.show_nr_jumps) {
					int prev;
					printed = scnprintf(bf, sizeof(bf), "%*d ",
							    notes->src->widths.jumps,
							    al->jump_sources);
					prev = obj__set_jumps_percent_color(obj, al->jump_sources,
									    current_entry);
					obj__printf(obj, bf);
					obj__set_color(obj, prev);
				}
print_addr:
				printed = scnprintf(bf, sizeof(bf), "%*" PRIx64 ": ",
						    notes->src->widths.target, addr);
			} else if (ins__is_call(&disasm_line(al)->ins) &&
				   annotate_opts.offset_level >= ANNOTATION__OFFSET_CALL) {
				goto print_addr;
			} else if (annotate_opts.offset_level == ANNOTATION__MAX_OFFSET_LEVEL) {
				goto print_addr;
			} else {
				printed = scnprintf(bf, sizeof(bf), "%-*s  ",
						    notes->src->widths.addr, " ");
			}
		}

		if (change_color)
			color = obj__set_color(obj, HE_COLORSET_ADDR);
		obj__printf(obj, bf);
		if (change_color)
			obj__set_color(obj, color);

		width -= printed;

		printed = disasm_line__write(disasm_line(al), notes, obj, bf, sizeof(bf),
					     obj__printf, obj__write_graph);

		obj__printf(obj, "%s", bf);
		width -= printed;

		disasm_line__snprint_type_info(disasm_line(al), bf, sizeof(bf), apd);
		obj__printf(obj, "%-*s", width, bf);
	}

}

int symbol__annotate2(struct map_symbol *ms, struct evsel *evsel,
		      const struct arch **parch)
{
	struct symbol *sym = ms->sym;
	struct annotation *notes = symbol__annotation(sym);
	size_t size = symbol__size(sym);
	int err;

	err = symbol__annotate(ms, evsel, parch);
	if (err)
		return err;

	symbol__calc_percent(sym, evsel);

	annotation__set_index(notes);
	annotation__mark_jump_targets(notes, sym);

	err = annotation__compute_ipc(notes, size, evsel);
	if (err)
		return err;

	annotation__init_column_widths(notes, sym);
	annotation__update_column_widths(notes);
	sym->annotate2 = 1;

	return 0;
}

const char * const perf_disassembler__strs[] = {
	[PERF_DISASM_UNKNOWN]  = "unknown",
	[PERF_DISASM_LLVM]     = "llvm",
	[PERF_DISASM_CAPSTONE] = "capstone",
	[PERF_DISASM_OBJDUMP]  = "objdump",
};


static void annotation_options__add_disassembler(struct annotation_options *options,
						 enum perf_disassembler dis)
{
	for (u8 i = 0; i < ARRAY_SIZE(options->disassemblers); i++) {
		if (options->disassemblers[i] == dis) {
			/* Disassembler is already present then don't add again. */
			return;
		}
		if (options->disassemblers[i] == PERF_DISASM_UNKNOWN) {
			/* Found a free slot. */
			options->disassemblers[i] = dis;
			return;
		}
	}
	pr_err("Failed to add disassembler %d\n", dis);
}

static int annotation_options__add_disassemblers_str(struct annotation_options *options,
						const char *str)
{
	while (str && *str != '\0') {
		const char *comma = strchr(str, ',');
		int len = comma ? comma - str : (int)strlen(str);
		bool match = false;

		for (u8 i = 0; i < ARRAY_SIZE(perf_disassembler__strs); i++) {
			const char *dis_str = perf_disassembler__strs[i];

			if (len == (int)strlen(dis_str) && !strncmp(str, dis_str, len)) {
				annotation_options__add_disassembler(options, i);
				match = true;
				break;
			}
		}
		if (!match) {
			pr_err("Invalid disassembler '%.*s'\n", len, str);
			return -1;
		}
		str = comma ? comma + 1 : NULL;
	}
	return 0;
}

static int annotation__config(const char *var, const char *value, void *data)
{
	struct annotation_options *opt = data;

	if (!strstarts(var, "annotate."))
		return 0;

	if (!strcmp(var, "annotate.offset_level")) {
		perf_config_u8(&opt->offset_level, "offset_level", value);

		if (opt->offset_level > ANNOTATION__MAX_OFFSET_LEVEL)
			opt->offset_level = ANNOTATION__MAX_OFFSET_LEVEL;
		else if (opt->offset_level < ANNOTATION__MIN_OFFSET_LEVEL)
			opt->offset_level = ANNOTATION__MIN_OFFSET_LEVEL;
	} else if (!strcmp(var, "annotate.disassemblers")) {
		int err = annotation_options__add_disassemblers_str(opt, value);

		if (err)
			return err;
	} else if (!strcmp(var, "annotate.hide_src_code")) {
		opt->hide_src_code = perf_config_bool("hide_src_code", value);
	} else if (!strcmp(var, "annotate.jump_arrows")) {
		opt->jump_arrows = perf_config_bool("jump_arrows", value);
	} else if (!strcmp(var, "annotate.show_linenr")) {
		opt->show_linenr = perf_config_bool("show_linenr", value);
	} else if (!strcmp(var, "annotate.show_nr_jumps")) {
		opt->show_nr_jumps = perf_config_bool("show_nr_jumps", value);
	} else if (!strcmp(var, "annotate.show_nr_samples")) {
		symbol_conf.show_nr_samples = perf_config_bool("show_nr_samples",
								value);
	} else if (!strcmp(var, "annotate.show_total_period")) {
		symbol_conf.show_total_period = perf_config_bool("show_total_period",
								value);
	} else if (!strcmp(var, "annotate.use_offset")) {
		opt->use_offset = perf_config_bool("use_offset", value);
	} else if (!strcmp(var, "annotate.disassembler_style")) {
		opt->disassembler_style = strdup(value);
		if (!opt->disassembler_style) {
			pr_err("Not enough memory for annotate.disassembler_style\n");
			return -1;
		}
	} else if (!strcmp(var, "annotate.objdump")) {
		opt->objdump_path = strdup(value);
		if (!opt->objdump_path) {
			pr_err("Not enough memory for annotate.objdump\n");
			return -1;
		}
	} else if (!strcmp(var, "annotate.addr2line")) {
		symbol_conf.addr2line_path = strdup(value);
		if (!symbol_conf.addr2line_path) {
			pr_err("Not enough memory for annotate.addr2line\n");
			return -1;
		}
	} else if (!strcmp(var, "annotate.demangle")) {
		symbol_conf.demangle = perf_config_bool("demangle", value);
	} else if (!strcmp(var, "annotate.demangle_kernel")) {
		symbol_conf.demangle_kernel = perf_config_bool("demangle_kernel", value);
	} else {
		pr_debug("%s variable unknown, ignoring...", var);
	}

	return 0;
}

void annotation_options__init(void)
{
	struct annotation_options *opt = &annotate_opts;

	memset(opt, 0, sizeof(*opt));

	/* Default values. */
	opt->use_offset = true;
	opt->jump_arrows = true;
	opt->annotate_src = true;
	opt->offset_level = ANNOTATION__OFFSET_JUMP_TARGETS;
	opt->percent_type = PERCENT_PERIOD_LOCAL;
	opt->hide_src_code = true;
	opt->hide_src_code_on_title = true;
}

void annotation_options__exit(void)
{
	zfree(&annotate_opts.disassembler_style);
	zfree(&annotate_opts.objdump_path);
}

static void annotation_options__default_init_disassemblers(struct annotation_options *options)
{
	if (options->disassemblers[0] != PERF_DISASM_UNKNOWN) {
		/* Already initialized. */
		return;
	}
#ifdef HAVE_LIBLLVM_SUPPORT
	annotation_options__add_disassembler(options, PERF_DISASM_LLVM);
#endif
#ifdef HAVE_LIBCAPSTONE_SUPPORT
	annotation_options__add_disassembler(options, PERF_DISASM_CAPSTONE);
#endif
	annotation_options__add_disassembler(options, PERF_DISASM_OBJDUMP);
}

void annotation_config__init(void)
{
	perf_config(annotation__config, &annotate_opts);
	annotation_options__default_init_disassemblers(&annotate_opts);
}

static unsigned int parse_percent_type(char *str1, char *str2)
{
	unsigned int type = (unsigned int) -1;

	if (!strcmp("period", str1)) {
		if (!strcmp("local", str2))
			type = PERCENT_PERIOD_LOCAL;
		else if (!strcmp("global", str2))
			type = PERCENT_PERIOD_GLOBAL;
	}

	if (!strcmp("hits", str1)) {
		if (!strcmp("local", str2))
			type = PERCENT_HITS_LOCAL;
		else if (!strcmp("global", str2))
			type = PERCENT_HITS_GLOBAL;
	}

	return type;
}

int annotate_parse_percent_type(const struct option *opt __maybe_unused, const char *_str,
				int unset __maybe_unused)
{
	unsigned int type;
	char *str1, *str2;
	int err = -1;

	str1 = strdup(_str);
	if (!str1)
		return -ENOMEM;

	str2 = strchr(str1, '-');
	if (!str2)
		goto out;

	*str2++ = 0;

	type = parse_percent_type(str1, str2);
	if (type == (unsigned int) -1)
		type = parse_percent_type(str2, str1);
	if (type != (unsigned int) -1) {
		annotate_opts.percent_type = type;
		err = 0;
	}

out:
	free(str1);
	return err;
}

int annotate_check_args(void)
{
	struct annotation_options *args = &annotate_opts;

	if (args->prefix_strip && !args->prefix) {
		pr_err("--prefix-strip requires --prefix\n");
		return -1;
	}
	return 0;
}

static int arch__dwarf_regnum(const struct arch *arch, const char *str)
{
	const char *p;
	char *regname, *q;
	int reg;

	p = strchr(str, arch->objdump.register_char);
	if (p == NULL)
		return -1;

	regname = strdup(p);
	if (regname == NULL)
		return -1;

	q = strpbrk(regname, ",) ");
	if (q)
		*q = '\0';

	reg = get_dwarf_regnum(regname, arch->id.e_machine, arch->id.e_flags);
	free(regname);
	return reg;
}

/*
 * Get register number and access offset from the given instruction.
 * It assumes AT&T x86 asm format like OFFSET(REG).  Maybe it needs
 * to revisit the format when it handles different architecture.
 * Fills @reg and @offset when return 0.
 */
static int extract_reg_offset(const struct arch *arch, const char *str,
			      struct annotated_op_loc *op_loc)
{
	char *p;

	if (arch->objdump.register_char == 0)
		return -1;

	/*
	 * It should start from offset, but it's possible to skip 0
	 * in the asm.  So 0(%rax) should be same as (%rax).
	 *
	 * However, it also start with a segment select register like
	 * %gs:0x18(%rbx).  In that case it should skip the part.
	 */
	if (*str == arch->objdump.register_char) {
		if (arch__is_x86(arch)) {
			/* FIXME: Handle other segment registers */
			if (!strncmp(str, "%gs:", 4))
				op_loc->segment = INSN_SEG_X86_GS;
		}

		while (*str && !isdigit(*str) &&
		       *str != arch->objdump.memory_ref_char)
			str++;
	}

	op_loc->offset = strtol(str, &p, 0);
	op_loc->reg1 = arch__dwarf_regnum(arch, p);
	if (op_loc->reg1 == -1)
		return -1;

	/* Get the second register */
	if (op_loc->multi_regs)
		op_loc->reg2 = arch__dwarf_regnum(arch, p + 1);

	return 0;
}

/**
 * annotate_get_insn_location - Get location of instruction
 * @arch: the architecture info
 * @dl: the target instruction
 * @loc: a buffer to save the data
 *
 * Get detailed location info (register and offset) in the instruction.
 * It needs both source and target operand and whether it accesses a
 * memory location.  The offset field is meaningful only when the
 * corresponding mem flag is set.  The reg2 field is meaningful only
 * when multi_regs flag is set.
 *
 * Some examples on x86:
 *
 *   mov  (%rax), %rcx   # src_reg1 = rax, src_mem = 1, src_offset = 0
 *                       # dst_reg1 = rcx, dst_mem = 0
 *
 *   mov  0x18, %r8      # src_reg1 = -1, src_mem = 0
 *                       # dst_reg1 = r8, dst_mem = 0
 *
 *   mov  %rsi, 8(%rbx,%rcx,4)  # src_reg1 = rsi, src_mem = 0, src_multi_regs = 0
 *                              # dst_reg1 = rbx, dst_reg2 = rcx, dst_mem = 1
 *                              # dst_multi_regs = 1, dst_offset = 8
 */
int annotate_get_insn_location(const struct arch *arch, struct disasm_line *dl,
			       struct annotated_insn_loc *loc)
{
	struct ins_operands *ops;
	struct annotated_op_loc *op_loc;
	int i;

	if (ins__is_lock(&dl->ins))
		ops = dl->ops.locked.ops;
	else
		ops = &dl->ops;

	if (ops == NULL)
		return -1;

	memset(loc, 0, sizeof(*loc));

	for_each_insn_op_loc(loc, i, op_loc) {
		const char *insn_str = ops->source.raw;
		bool multi_regs = ops->source.multi_regs;
		bool mem_ref = ops->source.mem_ref;

		if (i == INSN_OP_TARGET) {
			insn_str = ops->target.raw;
			multi_regs = ops->target.multi_regs;
			mem_ref = ops->target.mem_ref;
		}

		/* Invalidate the register by default */
		op_loc->reg1 = -1;
		op_loc->reg2 = -1;

		if (insn_str == NULL) {
			if (!arch__is_powerpc(arch))
				continue;
		}

		/*
		 * For powerpc, call get_powerpc_regs function which extracts the
		 * required fields for op_loc, ie reg1, reg2, offset from the
		 * raw instruction.
		 */
		if (arch__is_powerpc(arch)) {
			op_loc->mem_ref = mem_ref;
			op_loc->multi_regs = multi_regs;
			get_powerpc_regs(dl->raw.raw_insn, !i, op_loc);
		} else if (strchr(insn_str, arch->objdump.memory_ref_char)) {
			op_loc->mem_ref = true;
			op_loc->multi_regs = multi_regs;
			extract_reg_offset(arch, insn_str, op_loc);
		} else {
			const char *s = insn_str;
			char *p = NULL;

			if (arch__is_x86(arch)) {
				/* FIXME: Handle other segment registers */
				if (!strncmp(insn_str, "%gs:", 4)) {
					op_loc->segment = INSN_SEG_X86_GS;
					op_loc->offset = strtol(insn_str + 4,
								&p, 0);
					if (p && p != insn_str + 4)
						op_loc->imm = true;
					continue;
				}
			}

			if (*s == arch->objdump.register_char) {
				op_loc->reg1 = arch__dwarf_regnum(arch, s);
			}
			else if (*s == arch->objdump.imm_char) {
				op_loc->offset = strtol(s + 1, &p, 0);
				if (p && p != s + 1)
					op_loc->imm = true;
			}
		}
	}

	return 0;
}

static struct disasm_line *find_disasm_line(struct symbol *sym, u64 ip,
					    bool allow_update)
{
	struct disasm_line *dl;
	struct annotation *notes;

	notes = symbol__annotation(sym);

	list_for_each_entry(dl, &notes->src->source, al.node) {
		if (dl->al.offset == -1)
			continue;

		if (sym->start + dl->al.offset == ip) {
			/*
			 * llvm-objdump places "lock" in a separate line and
			 * in that case, we want to get the next line.
			 */
			if (ins__is_lock(&dl->ins) &&
			    *dl->ops.raw == '\0' && allow_update) {
				ip++;
				continue;
			}
			return dl;
		}
	}
	return NULL;
}

static struct annotated_item_stat *annotate_data_stat(struct list_head *head,
						      const char *name)
{
	struct annotated_item_stat *istat;

	list_for_each_entry(istat, head, list) {
		if (!strcmp(istat->name, name))
			return istat;
	}

	istat = zalloc(sizeof(*istat));
	if (istat == NULL)
		return NULL;

	istat->name = strdup(name);
	if ((istat->name == NULL) || (!strlen(istat->name))) {
		free(istat);
		return NULL;
	}

	list_add_tail(&istat->list, head);
	return istat;
}

static bool is_stack_operation(const struct arch *arch, struct disasm_line *dl)
{
	if (arch__is_x86(arch)) {
		if (!strncmp(dl->ins.name, "push", 4) ||
		    !strncmp(dl->ins.name, "pop", 3) ||
		    !strncmp(dl->ins.name, "call", 4) ||
		    !strncmp(dl->ins.name, "ret", 3))
			return true;
	}

	return false;
}

static bool is_stack_canary(const struct arch *arch, struct annotated_op_loc *loc)
{
	/* On x86_64, %gs:40 is used for stack canary */
	if (arch__is_x86(arch)) {
		if (loc->segment == INSN_SEG_X86_GS && loc->imm &&
		    loc->offset == 40)
			return true;
	}

	return false;
}

/**
 * Returns true if the instruction has a memory operand without
 * performing a load/store
 */
static bool is_address_gen_insn(const struct arch *arch, struct disasm_line *dl)
{
	if (arch__is_x86(arch)) {
		if (!strncmp(dl->ins.name, "lea", 3))
			return true;
	}

	return false;
}

static struct disasm_line *
annotation__prev_asm_line(struct annotation *notes, struct disasm_line *curr)
{
	struct list_head *sources = &notes->src->source;
	struct disasm_line *prev;

	if (curr == list_first_entry(sources, struct disasm_line, al.node))
		return NULL;

	prev = list_prev_entry(curr, al.node);
	while (prev->al.offset == -1 &&
	       prev != list_first_entry(sources, struct disasm_line, al.node))
		prev = list_prev_entry(prev, al.node);

	if (prev->al.offset == -1)
		return NULL;

	return prev;
}

static struct disasm_line *
annotation__next_asm_line(struct annotation *notes, struct disasm_line *curr)
{
	struct list_head *sources = &notes->src->source;
	struct disasm_line *next;

	if (curr == list_last_entry(sources, struct disasm_line, al.node))
		return NULL;

	next = list_next_entry(curr, al.node);
	while (next->al.offset == -1 &&
	       next != list_last_entry(sources, struct disasm_line, al.node))
		next = list_next_entry(next, al.node);

	if (next->al.offset == -1)
		return NULL;

	return next;
}

u64 annotate_calc_pcrel(struct map_symbol *ms, u64 ip, int offset,
			struct disasm_line *dl)
{
	struct annotation *notes;
	struct disasm_line *next;
	u64 addr;

	notes = symbol__annotation(ms->sym);
	/*
	 * PC-relative addressing starts from the next instruction address
	 * But the IP is for the current instruction.  Since disasm_line
	 * doesn't have the instruction size, calculate it using the next
	 * disasm_line.  If it's the last one, we can use symbol's end
	 * address directly.
	 */
	next = annotation__next_asm_line(notes, dl);
	if (next == NULL)
		addr = ms->sym->end + offset;
	else
		addr = ip + (next->al.offset - dl->al.offset) + offset;

	return map__rip_2objdump(ms->map, addr);
}

static struct debuginfo_cache {
	struct dso *dso;
	struct debuginfo *dbg;
} di_cache;

void debuginfo_cache__delete(void)
{
	dso__put(di_cache.dso);
	di_cache.dso = NULL;

	debuginfo__delete(di_cache.dbg);
	di_cache.dbg = NULL;
}

static struct annotated_data_type *
__hist_entry__get_data_type(struct hist_entry *he, const struct arch *arch,
			    struct debuginfo *dbg, struct disasm_line *dl,
			    int *type_offset)
{
	struct map_symbol *ms = &he->ms;
	struct annotated_insn_loc loc;
	struct annotated_op_loc *op_loc;
	struct annotated_data_type *mem_type;
	struct annotated_item_stat *istat;
	int i;

	istat = annotate_data_stat(&ann_insn_stat, dl->ins.name);
	if (istat == NULL) {
		ann_data_stat.no_insn++;
		return NO_TYPE;
	}

	if (annotate_get_insn_location(arch, dl, &loc) < 0) {
		ann_data_stat.no_insn_ops++;
		istat->bad++;
		return NO_TYPE;
	}

	if (is_stack_operation(arch, dl)) {
		istat->good++;
		*type_offset = 0;
		return &stackop_type;
	}

	if (is_address_gen_insn(arch, dl)) {
		istat->bad++;
		ann_data_stat.no_mem_ops++;
		return NO_TYPE;
	}

	for_each_insn_op_loc(&loc, i, op_loc) {
		struct data_loc_info dloc = {
			.arch = arch,
			.thread = he->thread,
			.ms = ms,
			.ip = ms->sym->start + dl->al.offset,
			.cpumode = he->cpumode,
			.op = op_loc,
			.di = dbg,
		};

		if (!op_loc->mem_ref && op_loc->segment == INSN_SEG_NONE)
			continue;

		/* PC-relative addressing */
		if (op_loc->reg1 == DWARF_REG_PC) {
			dloc.var_addr = annotate_calc_pcrel(ms, dloc.ip,
							    op_loc->offset, dl);
		}

		/* This CPU access in kernel - pretend PC-relative addressing */
		if (dso__kernel(map__dso(ms->map)) && arch__is_x86(arch) &&
		    op_loc->segment == INSN_SEG_X86_GS && op_loc->imm) {
			dloc.var_addr = op_loc->offset;
			op_loc->reg1 = DWARF_REG_PC;
		}

		mem_type = find_data_type(&dloc);

		if (mem_type == NULL && is_stack_canary(arch, op_loc)) {
			istat->good++;
			*type_offset = 0;
			return &canary_type;
		}

		if (mem_type)
			istat->good++;
		else
			istat->bad++;

		if (symbol_conf.annotate_data_sample) {
			struct evsel *evsel = hists_to_evsel(he->hists);

			annotated_data_type__update_samples(mem_type, evsel,
							    dloc.type_offset,
							    he->stat.nr_events,
							    he->stat.period);
		}
		*type_offset = dloc.type_offset;
		return mem_type ?: NO_TYPE;
	}

	/* retry with a fused instruction */
	return NULL;
}

/**
 * hist_entry__get_data_type - find data type for given hist entry
 * @he: hist entry
 *
 * This function first annotates the instruction at @he->ip and extracts
 * register and offset info from it.  Then it searches the DWARF debug
 * info to get a variable and type information using the address, register,
 * and offset.
 */
struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he)
{
	struct map_symbol *ms = &he->ms;
	struct evsel *evsel = hists_to_evsel(he->hists);
	const struct arch *arch;
	struct disasm_line *dl;
	struct annotated_data_type *mem_type;
	struct annotated_item_stat *istat;
	u64 ip = he->ip;

	ann_data_stat.total++;

	if (ms->map == NULL || ms->sym == NULL) {
		ann_data_stat.no_sym++;
		return NULL;
	}

	if (!symbol_conf.init_annotation) {
		ann_data_stat.no_sym++;
		return NULL;
	}

	/*
	 * di_cache holds a pair of values, but code below assumes
	 * di_cache.dso can be compared/updated and di_cache.dbg can be
	 * read/updated independently from each other. That assumption only
	 * holds in single threaded code.
	 */
	assert(perf_singlethreaded);

	if (map__dso(ms->map) != di_cache.dso) {
		dso__put(di_cache.dso);
		di_cache.dso = dso__get(map__dso(ms->map));

		debuginfo__delete(di_cache.dbg);
		di_cache.dbg = dso__debuginfo(di_cache.dso);
	}

	if (di_cache.dbg == NULL) {
		ann_data_stat.no_dbginfo++;
		return NULL;
	}

	/* Make sure it has the disasm of the function */
	if (symbol__annotate(ms, evsel, &arch) < 0) {
		ann_data_stat.no_insn++;
		return NULL;
	}

	/*
	 * Get a disasm to extract the location from the insn.
	 * This is too slow...
	 */
	dl = find_disasm_line(ms->sym, ip, /*allow_update=*/true);
	if (dl == NULL) {
		ann_data_stat.no_insn++;
		return NULL;
	}

retry:
	mem_type = __hist_entry__get_data_type(he, arch, di_cache.dbg, dl,
					       &he->mem_type_off);
	if (mem_type)
		return mem_type == NO_TYPE ? NULL : mem_type;

	/*
	 * Some instructions can be fused and the actual memory access came
	 * from the previous instruction.
	 */
	if (dl->al.offset > 0) {
		struct annotation *notes;
		struct disasm_line *prev_dl;

		notes = symbol__annotation(ms->sym);
		prev_dl = annotation__prev_asm_line(notes, dl);

		if (prev_dl && ins__is_fused(arch, prev_dl->ins.name, dl->ins.name)) {
			dl = prev_dl;
			goto retry;
		}
	}

	ann_data_stat.no_mem_ops++;
	istat = annotate_data_stat(&ann_insn_stat, dl->ins.name);
	if (istat)
		istat->bad++;
	return NULL;
}

/* Basic block traversal (BFS) data structure */
struct basic_block_data {
	struct list_head queue;
	struct list_head visited;
};

/*
 * During the traversal, it needs to know the parent block where the current
 * block block started from.  Note that single basic block can be parent of
 * two child basic blocks (in case of condition jump).
 */
struct basic_block_link {
	struct list_head node;
	struct basic_block_link *parent;
	struct annotated_basic_block *bb;
};

/* Check any of basic block in the list already has the offset */
static bool basic_block_has_offset(struct list_head *head, s64 offset)
{
	struct basic_block_link *link;

	list_for_each_entry(link, head, node) {
		s64 begin_offset = link->bb->begin->al.offset;
		s64 end_offset = link->bb->end->al.offset;

		if (begin_offset <= offset && offset <= end_offset)
			return true;
	}
	return false;
}

static bool is_new_basic_block(struct basic_block_data *bb_data,
			       struct disasm_line *dl)
{
	s64 offset = dl->al.offset;

	if (basic_block_has_offset(&bb_data->visited, offset))
		return false;
	if (basic_block_has_offset(&bb_data->queue, offset))
		return false;
	return true;
}

/* Add a basic block starting from dl and link it to the parent */
static int add_basic_block(struct basic_block_data *bb_data,
			   struct basic_block_link *parent,
			   struct disasm_line *dl)
{
	struct annotated_basic_block *bb;
	struct basic_block_link *link;

	if (dl == NULL)
		return -1;

	if (!is_new_basic_block(bb_data, dl))
		return 0;

	bb = zalloc(sizeof(*bb));
	if (bb == NULL)
		return -1;

	bb->begin = dl;
	bb->end = dl;
	INIT_LIST_HEAD(&bb->list);

	link = malloc(sizeof(*link));
	if (link == NULL) {
		free(bb);
		return -1;
	}

	link->bb = bb;
	link->parent = parent;
	list_add_tail(&link->node, &bb_data->queue);
	return 0;
}

/* Returns true when it finds the target in the current basic block */
static bool process_basic_block(struct basic_block_data *bb_data,
				struct basic_block_link *link,
				struct symbol *sym, u64 target)
{
	struct disasm_line *dl, *next_dl, *last_dl;
	struct annotation *notes = symbol__annotation(sym);
	bool found = false;

	dl = link->bb->begin;
	/* Check if it's already visited */
	if (basic_block_has_offset(&bb_data->visited, dl->al.offset))
		return false;

	last_dl = list_last_entry(&notes->src->source,
				  struct disasm_line, al.node);
	if (last_dl->al.offset == -1)
		last_dl = annotation__prev_asm_line(notes, last_dl);

	if (last_dl == NULL)
		return false;

	list_for_each_entry_from(dl, &notes->src->source, al.node) {
		/* Skip comment or debug info line */
		if (dl->al.offset == -1)
			continue;
		/* Found the target instruction */
		if (sym->start + dl->al.offset == target) {
			found = true;
			break;
		}
		/* End of the function, finish the block */
		if (dl == last_dl)
			break;
		/* 'return' instruction finishes the block */
		if (ins__is_ret(&dl->ins))
			break;
		/* normal instructions are part of the basic block */
		if (!ins__is_jump(&dl->ins))
			continue;
		/* jump to a different function, tail call or return */
		if (dl->ops.target.outside)
			break;
		/* jump instruction creates new basic block(s) */
		next_dl = find_disasm_line(sym, sym->start + dl->ops.target.offset,
					   /*allow_update=*/false);
		if (next_dl)
			add_basic_block(bb_data, link, next_dl);

		/*
		 * FIXME: determine conditional jumps properly.
		 * Conditional jumps create another basic block with the
		 * next disasm line.
		 */
		if (!strstr(dl->ins.name, "jmp")) {
			next_dl = annotation__next_asm_line(notes, dl);
			if (next_dl)
				add_basic_block(bb_data, link, next_dl);
		}
		break;

	}
	link->bb->end = dl;
	return found;
}

/*
 * It founds a target basic block, build a proper linked list of basic blocks
 * by following the link recursively.
 */
static void link_found_basic_blocks(struct basic_block_link *link,
				    struct list_head *head)
{
	while (link) {
		struct basic_block_link *parent = link->parent;

		list_move(&link->bb->list, head);
		list_del(&link->node);
		free(link);

		link = parent;
	}
}

static void delete_basic_blocks(struct basic_block_data *bb_data)
{
	struct basic_block_link *link, *tmp;

	list_for_each_entry_safe(link, tmp, &bb_data->queue, node) {
		list_del(&link->node);
		zfree(&link->bb);
		free(link);
	}

	list_for_each_entry_safe(link, tmp, &bb_data->visited, node) {
		list_del(&link->node);
		zfree(&link->bb);
		free(link);
	}
}

/**
 * annotate_get_basic_blocks - Get basic blocks for given address range
 * @sym: symbol to annotate
 * @src: source address
 * @dst: destination address
 * @head: list head to save basic blocks
 *
 * This function traverses disasm_lines from @src to @dst and save them in a
 * list of annotated_basic_block to @head.  It uses BFS to find the shortest
 * path between two.  The basic_block_link is to maintain parent links so
 * that it can build a list of blocks from the start.
 */
int annotate_get_basic_blocks(struct symbol *sym, s64 src, s64 dst,
			      struct list_head *head)
{
	struct basic_block_data bb_data = {
		.queue = LIST_HEAD_INIT(bb_data.queue),
		.visited = LIST_HEAD_INIT(bb_data.visited),
	};
	struct basic_block_link *link;
	struct disasm_line *dl;
	int ret = -1;

	dl = find_disasm_line(sym, src, /*allow_update=*/false);
	if (dl == NULL)
		return -1;

	if (add_basic_block(&bb_data, /*parent=*/NULL, dl) < 0)
		return -1;

	/* Find shortest path from src to dst using BFS */
	while (!list_empty(&bb_data.queue)) {
		link = list_first_entry(&bb_data.queue, struct basic_block_link, node);

		if (process_basic_block(&bb_data, link, sym, dst)) {
			link_found_basic_blocks(link, head);
			ret = 0;
			break;
		}
		list_move(&link->node, &bb_data.visited);
	}
	delete_basic_blocks(&bb_data);
	return ret;
}
