// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2015-2017 Josh Poimboeuf <jpoimboe@redhat.com>
 */

#define _GNU_SOURCE
#include <fnmatch.h>

#include <objtool/arch.h>
#include <objtool/check.h>
#include <objtool/disas.h>
#include <objtool/special.h>
#include <objtool/warn.h>

#include <bfd.h>
#include <linux/string.h>
#include <tools/dis-asm-compat.h>

/*
 * Size of the buffer for storing the result of disassembling
 * a single instruction.
 */
#define DISAS_RESULT_SIZE	1024

struct disas_context {
	struct objtool_file *file;
	struct instruction *insn;
	bool alt_applied;
	char result[DISAS_RESULT_SIZE];
	disassembler_ftype disassembler;
	struct disassemble_info info;
};

/*
 * Maximum number of alternatives
 */
#define DISAS_ALT_MAX		5

/*
 * Maximum number of instructions per alternative
 */
#define DISAS_ALT_INSN_MAX	50

/*
 * Information to disassemble an alternative
 */
struct disas_alt {
	struct instruction *orig_insn;		/* original instruction */
	struct alternative *alt;		/* alternative or NULL if default code */
	char *name;				/* name for this alternative */
	int width;				/* formatting width */
	struct {
		char *str;			/* instruction string */
		int offset;			/* instruction offset */
		int nops;			/* number of nops */
	} insn[DISAS_ALT_INSN_MAX];		/* alternative instructions */
	int insn_idx;				/* index of the next instruction to print */
};

#define DALT_DEFAULT(dalt)	(!(dalt)->alt)
#define DALT_INSN(dalt)		(DALT_DEFAULT(dalt) ? (dalt)->orig_insn : (dalt)->alt->insn)
#define DALT_GROUP(dalt)	(DALT_INSN(dalt)->alt_group)
#define DALT_ALTID(dalt)	((dalt)->orig_insn->offset)

#define ALT_FLAGS_SHIFT		16
#define ALT_FLAG_NOT		(1 << 0)
#define ALT_FLAG_DIRECT_CALL	(1 << 1)
#define ALT_FEATURE_MASK	((1 << ALT_FLAGS_SHIFT) - 1)

static int alt_feature(unsigned int ft_flags)
{
	return (ft_flags & ALT_FEATURE_MASK);
}

static int alt_flags(unsigned int ft_flags)
{
	return (ft_flags >> ALT_FLAGS_SHIFT);
}

/*
 * Wrapper around asprintf() to allocate and format a string.
 * Return the allocated string or NULL on error.
 */
static char *strfmt(const char *fmt, ...)
{
	va_list ap;
	char *str;
	int rv;

	va_start(ap, fmt);
	rv = vasprintf(&str, fmt, ap);
	va_end(ap);

	return rv == -1 ? NULL : str;
}

static int sprint_name(char *str, const char *name, unsigned long offset)
{
	int len;

	if (offset)
		len = sprintf(str, "%s+0x%lx", name, offset);
	else
		len = sprintf(str, "%s", name);

	return len;
}

#define DINFO_FPRINTF(dinfo, ...)	\
	((*(dinfo)->fprintf_func)((dinfo)->stream, __VA_ARGS__))
#define bfd_vma_fmt			\
	__builtin_choose_expr(sizeof(bfd_vma) == sizeof(unsigned long), "%#lx <%s>", "%#llx <%s>")

static int disas_result_fprintf(struct disas_context *dctx,
				const char *fmt, va_list ap)
{
	char *buf = dctx->result;
	int avail, len;

	len = strlen(buf);
	if (len >= DISAS_RESULT_SIZE - 1) {
		WARN_FUNC(dctx->insn->sec, dctx->insn->offset,
			  "disassembly buffer is full");
		return -1;
	}
	avail = DISAS_RESULT_SIZE - len;

	len = vsnprintf(buf + len, avail, fmt, ap);
	if (len < 0 || len >= avail) {
		WARN_FUNC(dctx->insn->sec, dctx->insn->offset,
			  "disassembly buffer is truncated");
		return -1;
	}

	return 0;
}

static int disas_fprintf(void *stream, const char *fmt, ...)
{
	va_list arg;
	int rv;

	va_start(arg, fmt);
	rv = disas_result_fprintf(stream, fmt, arg);
	va_end(arg);

	return rv;
}

/*
 * For init_disassemble_info_compat().
 */
static int disas_fprintf_styled(void *stream,
				enum disassembler_style style,
				const char *fmt, ...)
{
	va_list arg;
	int rv;

	va_start(arg, fmt);
	rv = disas_result_fprintf(stream, fmt, arg);
	va_end(arg);

	return rv;
}

static void disas_print_addr_sym(struct section *sec, struct symbol *sym,
				 bfd_vma addr, struct disassemble_info *dinfo)
{
	char symstr[1024];
	char *str;

	if (sym) {
		sprint_name(symstr, sym->name, addr - sym->offset);
		DINFO_FPRINTF(dinfo, bfd_vma_fmt, addr, symstr);
	} else {
		str = offstr(sec, addr);
		DINFO_FPRINTF(dinfo, bfd_vma_fmt, addr, str);
		free(str);
	}
}

static bool disas_print_addr_alt(bfd_vma addr, struct disassemble_info *dinfo)
{
	struct disas_context *dctx = dinfo->application_data;
	struct instruction *orig_first_insn;
	struct alt_group *alt_group;
	unsigned long offset;
	struct symbol *sym;

	/*
	 * Check if we are processing an alternative at the original
	 * instruction address (i.e. if alt_applied is true) and if
	 * we are referencing an address inside the alternative.
	 *
	 * For example, this happens if there is a branch inside an
	 * alternative. In that case, the address should be updated
	 * to a reference inside the original instruction flow.
	 */
	if (!dctx->alt_applied)
		return false;

	alt_group = dctx->insn->alt_group;
	if (!alt_group || !alt_group->orig_group ||
	    addr < alt_group->first_insn->offset ||
	    addr > alt_group->last_insn->offset)
		return false;

	orig_first_insn = alt_group->orig_group->first_insn;
	offset = addr - alt_group->first_insn->offset;

	addr = orig_first_insn->offset + offset;
	sym = insn_sym(orig_first_insn);

	disas_print_addr_sym(orig_first_insn->sec, sym, addr, dinfo);

	return true;
}

static void disas_print_addr_noreloc(bfd_vma addr,
				     struct disassemble_info *dinfo)
{
	struct disas_context *dctx = dinfo->application_data;
	struct instruction *insn = dctx->insn;
	struct symbol *sym = insn_sym(insn);

	if (disas_print_addr_alt(addr, dinfo))
		return;

	if (sym && (addr < sym->offset || addr >= sym->offset + sym->len))
		sym = NULL;

	disas_print_addr_sym(insn->sec, sym, addr, dinfo);
}

static void disas_print_addr_reloc(bfd_vma addr, struct disassemble_info *dinfo)
{
	struct disas_context *dctx = dinfo->application_data;
	struct instruction *insn = dctx->insn;
	unsigned long offset;
	struct reloc *reloc;
	char symstr[1024];
	char *str;

	reloc = find_reloc_by_dest_range(dctx->file->elf, insn->sec,
					 insn->offset, insn->len);
	if (!reloc) {
		/*
		 * There is no relocation for this instruction although
		 * the address to resolve points to the next instruction.
		 * So this is an effective reference to the next IP, for
		 * example: "lea 0x0(%rip),%rdi". The kernel can reference
		 * the next IP with _THIS_IP_ macro.
		 */
		DINFO_FPRINTF(dinfo, bfd_vma_fmt, addr, "_THIS_IP_");
		return;
	}

	offset = arch_insn_adjusted_addend(insn, reloc);

	/*
	 * If the relocation symbol is a section name (for example ".bss")
	 * then we try to further resolve the name.
	 */
	if (is_sec_sym(reloc->sym)) {
		str = offstr(reloc->sym->sec, reloc->sym->offset + offset);
		DINFO_FPRINTF(dinfo, bfd_vma_fmt, addr, str);
		free(str);
	} else {
		sprint_name(symstr, reloc->sym->name, offset);
		DINFO_FPRINTF(dinfo, bfd_vma_fmt, addr, symstr);
	}
}

/*
 * Resolve an address into a "<symbol>+<offset>" string.
 */
static void disas_print_address(bfd_vma addr, struct disassemble_info *dinfo)
{
	struct disas_context *dctx = dinfo->application_data;
	struct instruction *insn = dctx->insn;
	struct instruction *jump_dest;
	struct symbol *sym;
	bool is_reloc;

	/*
	 * If the instruction is a call/jump and it references a
	 * destination then this is likely the address we are looking
	 * up. So check it first.
	 */
	jump_dest = insn->jump_dest;
	if (jump_dest && insn_sym(jump_dest) && jump_dest->offset == addr) {
		if (!disas_print_addr_alt(addr, dinfo))
			disas_print_addr_sym(jump_dest->sec, insn_sym(jump_dest),
					     addr, dinfo);
		return;
	}

	/*
	 * If the address points to the next instruction then there is
	 * probably a relocation. It can be a false positive when the
	 * current instruction is referencing the address of the next
	 * instruction. This particular case will be handled in
	 * disas_print_addr_reloc().
	 */
	is_reloc = (addr == insn->offset + insn->len);

	/*
	 * The call destination offset can be the address we are looking
	 * up, or 0 if there is a relocation.
	 */
	sym = insn_call_dest(insn);
	if (sym && (sym->offset == addr || (sym->offset == 0 && is_reloc))) {
		DINFO_FPRINTF(dinfo, bfd_vma_fmt, addr, sym->name);
		return;
	}

	if (!is_reloc)
		disas_print_addr_noreloc(addr, dinfo);
	else
		disas_print_addr_reloc(addr, dinfo);
}

/*
 * Initialize disassemble info arch, mach (32 or 64-bit) and options.
 */
int disas_info_init(struct disassemble_info *dinfo,
		    int arch, int mach32, int mach64,
		    const char *options)
{
	struct disas_context *dctx = dinfo->application_data;
	struct objtool_file *file = dctx->file;

	dinfo->arch = arch;

	switch (file->elf->ehdr.e_ident[EI_CLASS]) {
	case ELFCLASS32:
		dinfo->mach = mach32;
		break;
	case ELFCLASS64:
		dinfo->mach = mach64;
		break;
	default:
		return -1;
	}

	dinfo->disassembler_options = options;

	return 0;
}

struct disas_context *disas_context_create(struct objtool_file *file)
{
	struct disas_context *dctx;
	struct disassemble_info *dinfo;
	int err;

	dctx = malloc(sizeof(*dctx));
	if (!dctx) {
		WARN("failed to allocate disassembly context");
		return NULL;
	}

	dctx->file = file;
	dinfo = &dctx->info;

	init_disassemble_info_compat(dinfo, dctx,
				     disas_fprintf, disas_fprintf_styled);

	dinfo->read_memory_func = buffer_read_memory;
	dinfo->print_address_func = disas_print_address;
	dinfo->application_data = dctx;

	/*
	 * bfd_openr() is not used to avoid doing ELF data processing
	 * and caching that has already being done. Here, we just need
	 * to identify the target file so we call an arch specific
	 * function to fill some disassemble info (arch, mach).
	 */

	dinfo->arch = bfd_arch_unknown;
	dinfo->mach = 0;

	err = arch_disas_info_init(dinfo);
	if (err || dinfo->arch == bfd_arch_unknown || dinfo->mach == 0) {
		WARN("failed to init disassembly arch");
		goto error;
	}

	dinfo->endian = (file->elf->ehdr.e_ident[EI_DATA] == ELFDATA2MSB) ?
		BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE;

	disassemble_init_for_target(dinfo);

	dctx->disassembler = disassembler(dinfo->arch,
					  dinfo->endian == BFD_ENDIAN_BIG,
					  dinfo->mach, NULL);
	if (!dctx->disassembler) {
		WARN("failed to create disassembler function");
		goto error;
	}

	return dctx;

error:
	free(dctx);
	return NULL;
}

void disas_context_destroy(struct disas_context *dctx)
{
	free(dctx);
}

char *disas_result(struct disas_context *dctx)
{
	return dctx->result;
}

#define DISAS_INSN_OFFSET_SPACE		10
#define DISAS_INSN_SPACE		60

#define DISAS_PRINSN(dctx, insn, depth)			\
	disas_print_insn(stdout, dctx, insn, depth, "\n")

/*
 * Print a message in the instruction flow. If sec is not NULL then the
 * address at the section offset is printed in addition of the message,
 * otherwise only the message is printed.
 */
static int disas_vprint(FILE *stream, struct section *sec, unsigned long offset,
			int depth, const char *format, va_list ap)
{
	const char *addr_str;
	int i, n;
	int len;

	len = sym_name_max_len + DISAS_INSN_OFFSET_SPACE;
	if (depth < 0) {
		len += depth;
		depth = 0;
	}

	n = 0;

	if (sec) {
		addr_str = offstr(sec, offset);
		n += fprintf(stream, "%6lx:  %-*s  ", offset, len, addr_str);
		free((char *)addr_str);
	} else {
		len += DISAS_INSN_OFFSET_SPACE + 1;
		n += fprintf(stream, "%-*s", len, "");
	}

	/* print vertical bars to show the code flow */
	for (i = 0; i < depth; i++)
		n += fprintf(stream, "| ");

	if (format)
		n += vfprintf(stream, format, ap);

	return n;
}

static int disas_print(FILE *stream, struct section *sec, unsigned long offset,
			int depth, const char *format, ...)
{
	va_list args;
	int len;

	va_start(args, format);
	len = disas_vprint(stream, sec, offset, depth, format, args);
	va_end(args);

	return len;
}

/*
 * Print a message in the instruction flow. If insn is not NULL then
 * the instruction address is printed in addition of the message,
 * otherwise only the message is printed. In all cases, the instruction
 * itself is not printed.
 */
void disas_print_info(FILE *stream, struct instruction *insn, int depth,
		      const char *format, ...)
{
	struct section *sec;
	unsigned long off;
	va_list args;

	if (insn) {
		sec = insn->sec;
		off = insn->offset;
	} else {
		sec = NULL;
		off = 0;
	}

	va_start(args, format);
	disas_vprint(stream, sec, off, depth, format, args);
	va_end(args);
}

/*
 * Print an instruction address (offset and function), the instruction itself
 * and an optional message.
 */
void disas_print_insn(FILE *stream, struct disas_context *dctx,
		      struct instruction *insn, int depth,
		      const char *format, ...)
{
	char fake_nop_insn[32];
	const char *insn_str;
	bool fake_nop;
	va_list args;
	int len;

	/*
	 * Alternative can insert a fake nop, sometimes with no
	 * associated section so nothing to disassemble.
	 */
	fake_nop = (!insn->sec && insn->type == INSN_NOP);
	if (fake_nop) {
		snprintf(fake_nop_insn, 32, "<fake nop> (%d bytes)", insn->len);
		insn_str = fake_nop_insn;
	} else {
		disas_insn(dctx, insn);
		insn_str = disas_result(dctx);
	}

	/* print the instruction */
	len = (depth + 1) * 2 < DISAS_INSN_SPACE ? DISAS_INSN_SPACE - (depth+1) * 2 : 1;
	disas_print_info(stream, insn, depth, "%-*s", len, insn_str);

	/* print message if any */
	if (!format)
		return;

	if (strcmp(format, "\n") == 0) {
		fprintf(stream, "\n");
		return;
	}

	fprintf(stream, " - ");
	va_start(args, format);
	vfprintf(stream, format, args);
	va_end(args);
}

/*
 * Disassemble a single instruction. Return the size of the instruction.
 *
 * If alt_applied is true then insn should be an instruction from of an
 * alternative (i.e. insn->alt_group != NULL), and it is disassembled
 * at the location of the original code it is replacing. When the
 * instruction references any address inside the alternative then
 * these references will be re-adjusted to replace the original code.
 */
static size_t disas_insn_common(struct disas_context *dctx,
				struct instruction *insn,
				bool alt_applied)
{
	disassembler_ftype disasm = dctx->disassembler;
	struct disassemble_info *dinfo = &dctx->info;

	dctx->insn = insn;
	dctx->alt_applied = alt_applied;
	dctx->result[0] = '\0';

	if (insn->type == INSN_NOP) {
		DINFO_FPRINTF(dinfo, "nop%d", insn->len);
		return insn->len;
	}

	/*
	 * Set the disassembler buffer to read data from the section
	 * containing the instruction to disassemble.
	 */
	dinfo->buffer = insn->sec->data->d_buf;
	dinfo->buffer_vma = 0;
	dinfo->buffer_length = sec_size(insn->sec);

	return disasm(insn->offset, &dctx->info);
}

size_t disas_insn(struct disas_context *dctx, struct instruction *insn)
{
	return disas_insn_common(dctx, insn, false);
}

static size_t disas_insn_alt(struct disas_context *dctx,
			     struct instruction *insn)
{
	return disas_insn_common(dctx, insn, true);
}

static struct instruction *next_insn_same_alt(struct objtool_file *file,
					      struct alt_group *alt_grp,
					      struct instruction *insn)
{
	if (alt_grp->last_insn == insn || alt_grp->nop == insn)
		return NULL;

	return next_insn_same_sec(file, insn);
}

#define alt_for_each_insn(file, alt_grp, insn)			\
	for (insn = alt_grp->first_insn; 			\
	     insn;						\
	     insn = next_insn_same_alt(file, alt_grp, insn))

/*
 * Provide a name for the type of alternatives present at the
 * specified instruction.
 *
 * An instruction can have alternatives with different types, for
 * example alternative instructions and an exception table. In that
 * case the name for the alternative instructions type is used.
 *
 * Return NULL if the instruction as no alternative.
 */
const char *disas_alt_type_name(struct instruction *insn)
{
	struct alternative *alt;
	const char *name;

	name = NULL;
	for (alt = insn->alts; alt; alt = alt->next) {
		if (alt->type == ALT_TYPE_INSTRUCTIONS) {
			name = "alternative";
			break;
		}

		switch (alt->type) {
		case ALT_TYPE_EX_TABLE:
			name = "ex_table";
			break;
		case ALT_TYPE_JUMP_TABLE:
			name = "jump_table";
			break;
		default:
			name = "unknown";
			break;
		}
	}

	return name;
}

/*
 * Provide a name for an alternative.
 */
char *disas_alt_name(struct alternative *alt)
{
	char pfx[4] = { 0 };
	char *str = NULL;
	const char *name;
	int feature;
	int flags;
	int num;

	switch (alt->type) {

	case ALT_TYPE_EX_TABLE:
		str = strdup("EXCEPTION");
		break;

	case ALT_TYPE_JUMP_TABLE:
		str = strdup("JUMP");
		break;

	case ALT_TYPE_INSTRUCTIONS:
		/*
		 * This is a non-default group alternative. Create a name
		 * based on the feature and flags associated with this
		 * alternative. Use either the feature name (it is available)
		 * or the feature number. And add a prefix to show the flags
		 * used.
		 *
		 * Prefix flags characters:
		 *
		 *   '!'  alternative used when feature not enabled
		 *   '+'  direct call alternative
		 *   '?'  unknown flag
		 */

		if (!alt->insn->alt_group)
			return NULL;

		feature = alt->insn->alt_group->feature;
		num = alt_feature(feature);
		flags = alt_flags(feature);
		str = pfx;

		if (flags & ~(ALT_FLAG_NOT | ALT_FLAG_DIRECT_CALL))
			*str++ = '?';
		if (flags & ALT_FLAG_DIRECT_CALL)
			*str++ = '+';
		if (flags & ALT_FLAG_NOT)
			*str++ = '!';

		name = arch_cpu_feature_name(num);
		if (!name)
			str = strfmt("%sFEATURE 0x%X", pfx, num);
		else
			str = strfmt("%s%s", pfx, name);

		break;
	}

	return str;
}

/*
 * Initialize an alternative. The default alternative should be initialized
 * with alt=NULL.
 */
static int disas_alt_init(struct disas_alt *dalt,
			  struct instruction *orig_insn,
			  struct alternative *alt)
{
	dalt->orig_insn = orig_insn;
	dalt->alt = alt;
	dalt->insn_idx = 0;
	dalt->name = alt ? disas_alt_name(alt) : strdup("DEFAULT");
	if (!dalt->name)
		return -1;
	dalt->width = strlen(dalt->name);

	return 0;
}

static int disas_alt_add_insn(struct disas_alt *dalt, int index, char *insn_str,
			      int offset, int nops)
{
	int len;

	if (index >= DISAS_ALT_INSN_MAX) {
		WARN("Alternative %lx.%s has more instructions than supported",
		     DALT_ALTID(dalt), dalt->name);
		return -1;
	}

	len = strlen(insn_str);
	dalt->insn[index].str = insn_str;
	dalt->insn[index].offset = offset;
	dalt->insn[index].nops = nops;
	if (len > dalt->width)
		dalt->width = len;

	return 0;
}

static int disas_alt_jump(struct disas_alt *dalt)
{
	struct instruction *orig_insn;
	struct instruction *dest_insn;
	char suffix[2] = { 0 };
	char *str;
	int nops;

	orig_insn = dalt->orig_insn;
	dest_insn = dalt->alt->insn;

	if (orig_insn->type == INSN_NOP) {
		if (orig_insn->len == 5)
			suffix[0] = 'q';
		str = strfmt("jmp%-3s %lx <%s+0x%lx>", suffix,
			     dest_insn->offset, insn_sym(dest_insn)->name,
			     dest_insn->offset - insn_sym(dest_insn)->offset);
		nops = 0;
	} else {
		str = strfmt("nop%d", orig_insn->len);
		nops = orig_insn->len;
	}

	if (!str)
		return -1;

	disas_alt_add_insn(dalt, 0, str, 0, nops);

	return 1;
}

/*
 * Disassemble an exception table alternative.
 */
static int disas_alt_extable(struct disas_alt *dalt)
{
	struct instruction *alt_insn;
	char *str;

	alt_insn = dalt->alt->insn;
	str = strfmt("resume at 0x%lx <%s+0x%lx>",
		     alt_insn->offset, insn_sym(alt_insn)->name,
		     alt_insn->offset - insn_sym(alt_insn)->offset);
	if (!str)
		return -1;

	disas_alt_add_insn(dalt, 0, str, 0, 0);

	return 1;
}

/*
 * Disassemble an alternative and store instructions in the disas_alt
 * structure. Return the number of instructions in the alternative.
 */
static int disas_alt_group(struct disas_context *dctx, struct disas_alt *dalt)
{
	struct objtool_file *file;
	struct instruction *insn;
	int offset;
	char *str;
	int count;
	int nops;
	int err;

	file = dctx->file;
	count = 0;
	offset = 0;
	nops = 0;

	alt_for_each_insn(file, DALT_GROUP(dalt), insn) {

		disas_insn_alt(dctx, insn);
		str = strdup(disas_result(dctx));
		if (!str)
			return -1;

		nops = insn->type == INSN_NOP ? insn->len : 0;
		err = disas_alt_add_insn(dalt, count, str, offset, nops);
		if (err)
			break;
		offset += insn->len;
		count++;
	}

	return count;
}

/*
 * Disassemble the default alternative.
 */
static int disas_alt_default(struct disas_context *dctx, struct disas_alt *dalt)
{
	char *str;
	int nops;
	int err;

	if (DALT_GROUP(dalt))
		return disas_alt_group(dctx, dalt);

	/*
	 * Default alternative with no alt_group: this is the default
	 * code associated with either a jump table or an exception
	 * table and no other instruction alternatives. In that case
	 * the default alternative is made of a single instruction.
	 */
	disas_insn(dctx, dalt->orig_insn);
	str = strdup(disas_result(dctx));
	if (!str)
		return -1;
	nops = dalt->orig_insn->type == INSN_NOP ? dalt->orig_insn->len : 0;
	err = disas_alt_add_insn(dalt, 0, str, 0, nops);
	if (err)
		return -1;

	return 1;
}

/*
 * For each alternative, if there is an instruction at the specified
 * offset then print this instruction, otherwise print a blank entry.
 * The offset is an offset from the start of the alternative.
 *
 * Return the offset for the next instructions to print, or -1 if all
 * instructions have been printed.
 */
static int disas_alt_print_insn(struct disas_alt *dalts, int alt_count,
				int insn_count, int offset)
{
	struct disas_alt *dalt;
	int offset_next;
	char *str;
	int i, j;

	offset_next = -1;

	for (i = 0; i < alt_count; i++) {
		dalt = &dalts[i];
		j = dalt->insn_idx;
		if (j == -1) {
			printf("| %-*s ", dalt->width, "");
			continue;
		}

		if (dalt->insn[j].offset == offset) {
			str = dalt->insn[j].str;
			printf("| %-*s ", dalt->width, str ?: "");
			if (++j < insn_count) {
				dalt->insn_idx = j;
			} else {
				dalt->insn_idx = -1;
				continue;
			}
		} else {
			printf("| %-*s ", dalt->width, "");
		}

		if (dalt->insn[j].offset > 0 &&
		    (offset_next == -1 ||
		     (dalt->insn[j].offset < offset_next)))
			offset_next = dalt->insn[j].offset;
	}
	printf("\n");

	return offset_next;
}

/*
 * Print all alternatives side-by-side.
 */
static void disas_alt_print_wide(char *alt_name, struct disas_alt *dalts, int alt_count,
				 int insn_count)
{
	struct instruction *orig_insn;
	int offset_next;
	int offset;
	int i;

	orig_insn = dalts[0].orig_insn;

	/*
	 * Print an header with the name of each alternative.
	 */
	disas_print_info(stdout, orig_insn, -2, NULL);

	if (strlen(alt_name) > dalts[0].width)
		dalts[0].width = strlen(alt_name);
	printf("| %-*s ", dalts[0].width, alt_name);

	for (i = 1; i < alt_count; i++)
		printf("| %-*s ", dalts[i].width, dalts[i].name);

	printf("\n");

	/*
	 * Print instructions for each alternative.
	 */
	offset_next = 0;
	do {
		offset = offset_next;
		disas_print(stdout, orig_insn->sec, orig_insn->offset + offset,
			    -2, NULL);
		offset_next = disas_alt_print_insn(dalts, alt_count, insn_count,
						   offset);
	} while (offset_next > offset);
}

/*
 * Print all alternatives one above the other.
 */
static void disas_alt_print_compact(char *alt_name, struct disas_alt *dalts,
				    int alt_count, int insn_count)
{
	struct instruction *orig_insn;
	int width;
	int i, j;
	int len;

	orig_insn = dalts[0].orig_insn;

	len = disas_print(stdout, orig_insn->sec, orig_insn->offset, 0, NULL);
	printf("%s\n", alt_name);

	/*
	 * If all alternatives have a single instruction then print each
	 * alternative on a single line. Otherwise, print alternatives
	 * one above the other with a clear separation.
	 */

	if (insn_count == 1) {
		width = 0;
		for (i = 0; i < alt_count; i++) {
			if (dalts[i].width > width)
				width = dalts[i].width;
		}

		for (i = 0; i < alt_count; i++) {
			printf("%*s= %-*s    (if %s)\n", len, "", width,
			       dalts[i].insn[0].str, dalts[i].name);
		}

		return;
	}

	for (i = 0; i < alt_count; i++) {
		printf("%*s= %s\n", len, "", dalts[i].name);
		for (j = 0; j < insn_count; j++) {
			if (!dalts[i].insn[j].str)
				break;
			disas_print(stdout, orig_insn->sec,
				    orig_insn->offset + dalts[i].insn[j].offset, 0,
				    "| %s\n", dalts[i].insn[j].str);
		}
		printf("%*s|\n", len, "");
	}
}

/*
 * Trim NOPs in alternatives. This replaces trailing NOPs in alternatives
 * with a single indication of the number of bytes covered with NOPs.
 *
 * Return the maximum numbers of instructions in all alternatives after
 * trailing NOPs have been trimmed.
 */
static int disas_alt_trim_nops(struct disas_alt *dalts, int alt_count,
			       int insn_count)
{
	struct disas_alt *dalt;
	int nops_count;
	const char *s;
	int offset;
	int count;
	int nops;
	int i, j;

	count = 0;
	for (i = 0; i < alt_count; i++) {
		offset = 0;
		nops = 0;
		nops_count = 0;
		dalt = &dalts[i];
		for (j = insn_count - 1; j >= 0; j--) {
			if (!dalt->insn[j].str || !dalt->insn[j].nops)
				break;
			offset = dalt->insn[j].offset;
			free(dalt->insn[j].str);
			dalt->insn[j].offset = 0;
			dalt->insn[j].str = NULL;
			nops += dalt->insn[j].nops;
			nops_count++;
		}

		/*
		 * All trailing NOPs have been removed. If there was a single
		 * NOP instruction then re-add it. If there was a block of
		 * NOPs then indicate the number of bytes than the block
		 * covers (nop*<number-of-bytes>).
		 */
		if (nops_count) {
			s = nops_count == 1 ? "" : "*";
			dalt->insn[j + 1].str = strfmt("nop%s%d", s, nops);
			dalt->insn[j + 1].offset = offset;
			dalt->insn[j + 1].nops = nops;
			j++;
		}

		if (j > count)
			count = j;
	}

	return count + 1;
}

/*
 * Disassemble an alternative.
 *
 * Return the last instruction in the default alternative so that
 * disassembly can continue with the next instruction. Return NULL
 * on error.
 */
static void *disas_alt(struct disas_context *dctx,
		       struct instruction *orig_insn)
{
	struct disas_alt dalts[DISAS_ALT_MAX] = { 0 };
	struct instruction *last_insn = NULL;
	struct alternative *alt;
	struct disas_alt *dalt;
	int insn_count = 0;
	int alt_count = 0;
	char *alt_name;
	int count;
	int i, j;
	int err;

	alt_name = strfmt("<%s.%lx>", disas_alt_type_name(orig_insn),
			  orig_insn->offset);
	if (!alt_name) {
		WARN("Failed to define name for alternative at instruction 0x%lx",
		     orig_insn->offset);
		goto done;
	}

	/*
	 * Initialize and disassemble the default alternative.
	 */
	err = disas_alt_init(&dalts[0], orig_insn, NULL);
	if (err) {
		WARN("%s: failed to initialize default alternative", alt_name);
		goto done;
	}

	insn_count = disas_alt_default(dctx, &dalts[0]);
	if (insn_count < 0) {
		WARN("%s: failed to disassemble default alternative", alt_name);
		goto done;
	}

	/*
	 * Initialize and disassemble all other alternatives.
	 */
	i = 1;
	for (alt = orig_insn->alts; alt; alt = alt->next) {
		if (i >= DISAS_ALT_MAX) {
			WARN("%s has more alternatives than supported", alt_name);
			break;
		}

		dalt = &dalts[i];
		err = disas_alt_init(dalt, orig_insn, alt);
		if (err) {
			WARN("%s: failed to disassemble alternative", alt_name);
			goto done;
		}

		count = -1;
		switch (dalt->alt->type) {
		case ALT_TYPE_INSTRUCTIONS:
			count = disas_alt_group(dctx, dalt);
			break;
		case ALT_TYPE_EX_TABLE:
			count = disas_alt_extable(dalt);
			break;
		case ALT_TYPE_JUMP_TABLE:
			count = disas_alt_jump(dalt);
			break;
		}
		if (count < 0) {
			WARN("%s: failed to disassemble alternative %s",
			     alt_name, dalt->name);
			goto done;
		}

		insn_count = count > insn_count ? count : insn_count;
		i++;
	}
	alt_count = i;

	/*
	 * Print default and non-default alternatives.
	 */

	insn_count = disas_alt_trim_nops(dalts, alt_count, insn_count);

	if (opts.wide)
		disas_alt_print_wide(alt_name, dalts, alt_count, insn_count);
	else
		disas_alt_print_compact(alt_name, dalts, alt_count, insn_count);

	last_insn = orig_insn->alt_group ? orig_insn->alt_group->last_insn :
		orig_insn;

done:
	for (i = 0; i < alt_count; i++) {
		free(dalts[i].name);
		for (j = 0; j < insn_count; j++)
			free(dalts[i].insn[j].str);
	}

	free(alt_name);

	return last_insn;
}

/*
 * Disassemble a function.
 */
static void disas_func(struct disas_context *dctx, struct symbol *func)
{
	struct instruction *insn_start;
	struct instruction *insn;

	printf("%s:\n", func->name);
	sym_for_each_insn(dctx->file, func, insn) {
		if (insn->alts) {
			insn_start = insn;
			insn = disas_alt(dctx, insn);
			if (insn)
				continue;
			/*
			 * There was an error with disassembling
			 * the alternative. Resume disassembling
			 * at the current instruction, this will
			 * disassemble the default alternative
			 * only and continue with the code after
			 * the alternative.
			 */
			insn = insn_start;
		}

		DISAS_PRINSN(dctx, insn, 0);
	}
	printf("\n");
}

/*
 * Disassemble all warned functions.
 */
void disas_warned_funcs(struct disas_context *dctx)
{
	struct symbol *sym;

	if (!dctx)
		return;

	for_each_sym(dctx->file->elf, sym) {
		if (sym->warned)
			disas_func(dctx, sym);
	}
}

void disas_funcs(struct disas_context *dctx)
{
	bool disas_all = !strcmp(opts.disas, "*");
	struct section *sec;
	struct symbol *sym;

	for_each_sec(dctx->file->elf, sec) {

		if (!is_text_sec(sec))
			continue;

		sec_for_each_sym(sec, sym) {
			/*
			 * If the function had a warning and the verbose
			 * option is used then the function was already
			 * disassemble.
			 */
			if (opts.verbose && sym->warned)
				continue;

			if (disas_all || fnmatch(opts.disas, sym->name, 0) == 0)
				disas_func(dctx, sym);
		}
	}
}
