// SPDX-License-Identifier: GPL-2.0-or-later
#include <string.h>

#include <arch/special.h>
#include <objtool/special.h>
#include <objtool/builtin.h>
#include <objtool/warn.h>
#include <asm/cpufeatures.h>

/* cpu feature name array generated from cpufeatures.h */
#include "cpu-feature-names.c"

/*
 * An alternative with an empty replacement, e.g. the second entry of
 *
 *   ALTERNATIVE_2("orig", "repl", ft1, "", ft2)
 *
 * still gets a relocation for its replacement offset.  But the label it points
 * at is the end of the previous entry's replacement, which is also the
 * beginning of the *next* entry's replacement.  The value is meaningless: it's
 * only ever used with a length of zero.
 */
bool arch_alt_ignore_new_reloc(struct section *sec, unsigned long offset)
{
	unsigned long entry_off;

	if (strcmp(sec->name, ".altinstructions"))
		return false;

	entry_off = offset - (offset % ALT_ENTRY_SIZE);

	if (offset - entry_off != ALT_NEW_OFFSET)
		return false;

	return !*(unsigned char *)(sec->data->d_buf + entry_off +
				   ALT_NEW_LEN_OFFSET);
}

void arch_handle_alternative(struct special_alt *alt)
{
	static struct special_alt *group, *prev;

	/*
	 * Recompute orig_len for nested ALTERNATIVE()s.
	 */
	if (group && group->orig_sec == alt->orig_sec &&
	             group->orig_off == alt->orig_off) {

		struct special_alt *iter = group;
		for (;;) {
			unsigned int len = max(iter->orig_len, alt->orig_len);
			iter->orig_len = alt->orig_len = len;

			if (iter == prev)
				break;

			iter = list_next_entry(iter, list);
		}

	} else group = alt;

	prev = alt;
}

bool arch_support_alt_relocation(struct special_alt *special_alt,
				 struct instruction *insn,
				 struct reloc *reloc)
{
	return true;
}

/*
 * There are 3 basic jump table patterns:
 *
 * 1. jmpq *[rodata addr](,%reg,8)
 *
 *    This is the most common case by far.  It jumps to an address in a simple
 *    jump table which is stored in .rodata.
 *
 * 2. jmpq *[rodata addr](%rip)
 *
 *    This is caused by a rare GCC quirk, currently only seen in three driver
 *    functions in the kernel, only with certain obscure non-distro configs.
 *
 *    As part of an optimization, GCC makes a copy of an existing switch jump
 *    table, modifies it, and then hard-codes the jump (albeit with an indirect
 *    jump) to use a single entry in the table.  The rest of the jump table and
 *    some of its jump targets remain as dead code.
 *
 *    In such a case we can just crudely ignore all unreachable instruction
 *    warnings for the entire object file.  Ideally we would just ignore them
 *    for the function, but that would require redesigning the code quite a
 *    bit.  And honestly that's just not worth doing: unreachable instruction
 *    warnings are of questionable value anyway, and this is such a rare issue.
 *
 * 3. mov [rodata addr],%reg1
 *    ... some instructions ...
 *    jmpq *(%reg1,%reg2,8)
 *
 *    This is a fairly uncommon pattern which is new for GCC 6.  As of this
 *    writing, there are 11 occurrences of it in the allmodconfig kernel.
 *
 *    As of GCC 7 there are quite a few more of these and the 'in between' code
 *    is significant. Esp. with KASAN enabled some of the code between the mov
 *    and jmpq uses .rodata itself, which can confuse things.
 *
 *    TODO: Once we have DWARF CFI and smarter instruction decoding logic,
 *    ensure the same register is used in the mov and jump instructions.
 *
 *    NOTE: MITIGATION_RETPOLINE made it harder still to decode dynamic jumps.
 */
struct reloc *arch_find_switch_table(struct objtool_file *file,
				     struct instruction *insn,
				     unsigned long *table_size)
{
	struct reloc  *text_reloc, *rodata_reloc;
	struct section *table_sec;
	unsigned long table_offset;

	/* look for a relocation which references .rodata */
	text_reloc = find_reloc_by_dest_range(file->elf, insn->sec,
					      insn->offset, insn->len);
	if (!text_reloc || !is_sec_sym(text_reloc->sym) ||
	    !text_reloc->sym->sec->rodata)
		return NULL;

	table_offset = reloc_addend(text_reloc);
	table_sec = text_reloc->sym->sec;

	if (reloc_type(text_reloc) == R_X86_64_PC32)
		table_offset += 4;

	/*
	 * Make sure the .rodata address isn't associated with a
	 * symbol.  GCC jump tables are anonymous data.
	 *
	 * Also support C jump tables which are in the same format as
	 * switch jump tables.  For objtool to recognize them, they
	 * need to be placed in the C_JUMP_TABLE_SECTION section.  They
	 * have symbols associated with them.
	 */
	if (find_symbol_containing(table_sec, table_offset) &&
	    strcmp(table_sec->name, C_JUMP_TABLE_SECTION))
		return NULL;

	/*
	 * Each table entry has a rela associated with it.  The rela
	 * should reference text in the same function as the original
	 * instruction.
	 */
	rodata_reloc = find_reloc_by_dest(file->elf, table_sec, table_offset);
	if (!rodata_reloc)
		return NULL;

	/*
	 * Use of RIP-relative switch jumps is quite rare, and
	 * indicates a rare GCC quirk/bug which can leave dead
	 * code behind.
	 */
	if (!file->ignore_unreachables && reloc_type(text_reloc) == R_X86_64_PC32) {
		WARN_INSN(insn, "ignoring unreachables due to jump table quirk");
		file->ignore_unreachables = true;
	}

	*table_size = 0;
	return rodata_reloc;
}

const char *arch_cpu_feature_name(int feature_number)
{
	return (feature_number < ARRAY_SIZE(cpu_feature_names)) ?
		cpu_feature_names[feature_number] : NULL;
}
