/*
 * IA-64-specific support for kernel module loader.
 *
 * Copyright (C) 2003 Hewlett-Packard Co
 *	David Mosberger-Tang <davidm@hpl.hp.com>
 *
 * Loosely based on patch by Rusty Russell.
 */

/* relocs tested so far:

   DIR64LSB
   FPTR64LSB
   GPREL22
   LDXMOV
   LDXMOV
   LTOFF22
   LTOFF22X
   LTOFF22X
   LTOFF_FPTR22
   PCREL21B	(for br.call only; br.cond is not supported out of modules!)
   PCREL60B	(for brl.cond only; brl.call is not supported for modules!)
   PCREL64LSB
   SECREL32LSB
   SEGREL64LSB
 */


#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/elf.h>
#include <linux/moduleloader.h>
#include <linux/string.h>
#include <linux/vmalloc.h>

#include <asm/patch.h>
#include <asm/unaligned.h>

#define ARCH_MODULE_DEBUG 0

#if ARCH_MODULE_DEBUG
# define DEBUGP printk
# define inline
#else
# define DEBUGP(fmt , a...)
#endif

#ifdef CONFIG_ITANIUM
# define USE_BRL	0
#else
# define USE_BRL	1
#endif

#define MAX_LTOFF	((uint64_t) (1 << 22))	/* max. allowable linkage-table offset */

/* Define some relocation helper macros/types: */

#define FORMAT_SHIFT	0
#define FORMAT_BITS	3
#define FORMAT_MASK	((1 << FORMAT_BITS) - 1)
#define VALUE_SHIFT	3
#define VALUE_BITS	5
#define VALUE_MASK	((1 << VALUE_BITS) - 1)

enum reloc_target_format {
	/* direct encoded formats: */
	RF_NONE = 0,
	RF_INSN14 = 1,
	RF_INSN22 = 2,
	RF_INSN64 = 3,
	RF_32MSB = 4,
	RF_32LSB = 5,
	RF_64MSB = 6,
	RF_64LSB = 7,

	/* formats that cannot be directly decoded: */
	RF_INSN60,
	RF_INSN21B,	/* imm21 form 1 */
	RF_INSN21M,	/* imm21 form 2 */
	RF_INSN21F	/* imm21 form 3 */
};

enum reloc_value_formula {
	RV_DIRECT = 4,		/* S + A */
	RV_GPREL = 5,		/* @gprel(S + A) */
	RV_LTREL = 6,		/* @ltoff(S + A) */
	RV_PLTREL = 7,		/* @pltoff(S + A) */
	RV_FPTR = 8,		/* @fptr(S + A) */
	RV_PCREL = 9,		/* S + A - P */
	RV_LTREL_FPTR = 10,	/* @ltoff(@fptr(S + A)) */
	RV_SEGREL = 11,		/* @segrel(S + A) */
	RV_SECREL = 12,		/* @secrel(S + A) */
	RV_BDREL = 13,		/* BD + A */
	RV_LTV = 14,		/* S + A (like RV_DIRECT, except frozen at static link-time) */
	RV_PCREL2 = 15,		/* S + A - P */
	RV_SPECIAL = 16,	/* various (see below) */
	RV_RSVD17 = 17,
	RV_TPREL = 18,		/* @tprel(S + A) */
	RV_LTREL_TPREL = 19,	/* @ltoff(@tprel(S + A)) */
	RV_DTPMOD = 20,		/* @dtpmod(S + A) */
	RV_LTREL_DTPMOD = 21,	/* @ltoff(@dtpmod(S + A)) */
	RV_DTPREL = 22,		/* @dtprel(S + A) */
	RV_LTREL_DTPREL = 23,	/* @ltoff(@dtprel(S + A)) */
	RV_RSVD24 = 24,
	RV_RSVD25 = 25,
	RV_RSVD26 = 26,
	RV_RSVD27 = 27
	/* 28-31 reserved for implementation-specific purposes.  */
};

#define N(reloc)	[R_IA64_##reloc] = #reloc

static const char *reloc_name[256] = {
	N(NONE),		N(IMM14),		N(IMM22),		N(IMM64),
	N(DIR32MSB),		N(DIR32LSB),		N(DIR64MSB),		N(DIR64LSB),
	N(GPREL22),		N(GPREL64I),		N(GPREL32MSB),		N(GPREL32LSB),
	N(GPREL64MSB),		N(GPREL64LSB),		N(LTOFF22),		N(LTOFF64I),
	N(PLTOFF22),		N(PLTOFF64I),		N(PLTOFF64MSB),		N(PLTOFF64LSB),
	N(FPTR64I),		N(FPTR32MSB),		N(FPTR32LSB),		N(FPTR64MSB),
	N(FPTR64LSB),		N(PCREL60B),		N(PCREL21B),		N(PCREL21M),
	N(PCREL21F),		N(PCREL32MSB),		N(PCREL32LSB),		N(PCREL64MSB),
	N(PCREL64LSB),		N(LTOFF_FPTR22),	N(LTOFF_FPTR64I),	N(LTOFF_FPTR32MSB),
	N(LTOFF_FPTR32LSB),	N(LTOFF_FPTR64MSB),	N(LTOFF_FPTR64LSB),	N(SEGREL32MSB),
	N(SEGREL32LSB),		N(SEGREL64MSB),		N(SEGREL64LSB),		N(SECREL32MSB),
	N(SECREL32LSB),		N(SECREL64MSB),		N(SECREL64LSB),		N(REL32MSB),
	N(REL32LSB),		N(REL64MSB),		N(REL64LSB),		N(LTV32MSB),
	N(LTV32LSB),		N(LTV64MSB),		N(LTV64LSB),		N(PCREL21BI),
	N(PCREL22),		N(PCREL64I),		N(IPLTMSB),		N(IPLTLSB),
	N(COPY),		N(LTOFF22X),		N(LDXMOV),		N(TPREL14),
	N(TPREL22),		N(TPREL64I),		N(TPREL64MSB),		N(TPREL64LSB),
	N(LTOFF_TPREL22),	N(DTPMOD64MSB),		N(DTPMOD64LSB),		N(LTOFF_DTPMOD22),
	N(DTPREL14),		N(DTPREL22),		N(DTPREL64I),		N(DTPREL32MSB),
	N(DTPREL32LSB),		N(DTPREL64MSB),		N(DTPREL64LSB),		N(LTOFF_DTPREL22)
};

#undef N

/* Opaque struct for insns, to protect against derefs. */
struct insn;

static inline uint64_t
bundle (const struct insn *insn)
{
	return (uint64_t) insn & ~0xfUL;
}

static inline int
slot (const struct insn *insn)
{
	return (uint64_t) insn & 0x3;
}

static int
apply_imm64 (struct module *mod, struct insn *insn, uint64_t val)
{
	if (slot(insn) != 2) {
		printk(KERN_ERR "%s: invalid slot number %d for IMM64\n",
		       mod->name, slot(insn));
		return 0;
	}
	ia64_patch_imm64((u64) insn, val);
	return 1;
}

static int
apply_imm60 (struct module *mod, struct insn *insn, uint64_t val)
{
	if (slot(insn) != 2) {
		printk(KERN_ERR "%s: invalid slot number %d for IMM60\n",
		       mod->name, slot(insn));
		return 0;
	}
	if (val + ((uint64_t) 1 << 59) >= (1UL << 60)) {
		printk(KERN_ERR "%s: value %ld out of IMM60 range\n", mod->name, (int64_t) val);
		return 0;
	}
	ia64_patch_imm60((u64) insn, val);
	return 1;
}

static int
apply_imm22 (struct module *mod, struct insn *insn, uint64_t val)
{
	if (val + (1 << 21) >= (1 << 22)) {
		printk(KERN_ERR "%s: value %li out of IMM22 range\n", mod->name, (int64_t)val);
		return 0;
	}
	ia64_patch((u64) insn, 0x01fffcfe000UL, (  ((val & 0x200000UL) << 15) /* bit 21 -> 36 */
					         | ((val & 0x1f0000UL) <<  6) /* bit 16 -> 22 */
					         | ((val & 0x00ff80UL) << 20) /* bit  7 -> 27 */
					         | ((val & 0x00007fUL) << 13) /* bit  0 -> 13 */));
	return 1;
}

static int
apply_imm21b (struct module *mod, struct insn *insn, uint64_t val)
{
	if (val + (1 << 20) >= (1 << 21)) {
		printk(KERN_ERR "%s: value %li out of IMM21b range\n", mod->name, (int64_t)val);
		return 0;
	}
	ia64_patch((u64) insn, 0x11ffffe000UL, (  ((val & 0x100000UL) << 16) /* bit 20 -> 36 */
					        | ((val & 0x0fffffUL) << 13) /* bit  0 -> 13 */));
	return 1;
}

#if USE_BRL

struct plt_entry {
	/* Three instruction bundles in PLT. */
 	unsigned char bundle[2][16];
};

static const struct plt_entry ia64_plt_template = {
	{
		{
			0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
			0x00, 0x00, 0x00, 0x00, 0x00, 0x20, /*	     movl gp=TARGET_GP */
			0x00, 0x00, 0x00, 0x60
		},
		{
			0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*	     brl.many gp=TARGET_GP */
			0x08, 0x00, 0x00, 0xc0
		}
	}
};

static int
patch_plt (struct module *mod, struct plt_entry *plt, long target_ip, unsigned long target_gp)
{
	if (apply_imm64(mod, (struct insn *) (plt->bundle[0] + 2), target_gp)
	    && apply_imm60(mod, (struct insn *) (plt->bundle[1] + 2),
			   (target_ip - (int64_t) plt->bundle[1]) / 16))
		return 1;
	return 0;
}

unsigned long
plt_target (struct plt_entry *plt)
{
	uint64_t b0, b1, *b = (uint64_t *) plt->bundle[1];
	long off;

	b0 = b[0]; b1 = b[1];
	off = (  ((b1 & 0x00fffff000000000UL) >> 36)		/* imm20b -> bit 0 */
	       | ((b0 >> 48) << 20) | ((b1 & 0x7fffffUL) << 36)	/* imm39 -> bit 20 */
	       | ((b1 & 0x0800000000000000UL) << 0));		/* i -> bit 59 */
	return (long) plt->bundle[1] + 16*off;
}

#else /* !USE_BRL */

struct plt_entry {
	/* Three instruction bundles in PLT. */
 	unsigned char bundle[3][16];
};

static const struct plt_entry ia64_plt_template = {
	{
		{
			0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*	     movl r16=TARGET_IP */
			0x02, 0x00, 0x00, 0x60
		},
		{
			0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
			0x00, 0x00, 0x00, 0x00, 0x00, 0x20, /*	     movl gp=TARGET_GP */
			0x00, 0x00, 0x00, 0x60
		},
		{
			0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
			0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /*	     mov b6=r16 */
			0x60, 0x00, 0x80, 0x00		    /*	     br.few b6 */
		}
	}
};

static int
patch_plt (struct module *mod, struct plt_entry *plt, long target_ip, unsigned long target_gp)
{
	if (apply_imm64(mod, (struct insn *) (plt->bundle[0] + 2), target_ip)
	    && apply_imm64(mod, (struct insn *) (plt->bundle[1] + 2), target_gp))
		return 1;
	return 0;
}

unsigned long
plt_target (struct plt_entry *plt)
{
	uint64_t b0, b1, *b = (uint64_t *) plt->bundle[0];

	b0 = b[0]; b1 = b[1];
	return (  ((b1 & 0x000007f000000000) >> 36)		/* imm7b -> bit 0 */
		| ((b1 & 0x07fc000000000000) >> 43)		/* imm9d -> bit 7 */
		| ((b1 & 0x0003e00000000000) >> 29)		/* imm5c -> bit 16 */
		| ((b1 & 0x0000100000000000) >> 23)		/* ic -> bit 21 */
		| ((b0 >> 46) << 22) | ((b1 & 0x7fffff) << 40)	/* imm41 -> bit 22 */
		| ((b1 & 0x0800000000000000) <<  4));		/* i -> bit 63 */
}

#endif /* !USE_BRL */

void *
module_alloc (unsigned long size)
{
	if (!size)
		return NULL;
	return vmalloc(size);
}

void
module_free (struct module *mod, void *module_region)
{
	if (mod && mod->arch.init_unw_table &&
	    module_region == mod->module_init) {
		unw_remove_unwind_table(mod->arch.init_unw_table);
		mod->arch.init_unw_table = NULL;
	}
	vfree(module_region);
}

/* Have we already seen one of these relocations? */
/* FIXME: we could look in other sections, too --RR */
static int
duplicate_reloc (const Elf64_Rela *rela, unsigned int num)
{
	unsigned int i;

	for (i = 0; i < num; i++) {
		if (rela[i].r_info == rela[num].r_info && rela[i].r_addend == rela[num].r_addend)
			return 1;
	}
	return 0;
}

/* Count how many GOT entries we may need */
static unsigned int
count_gots (const Elf64_Rela *rela, unsigned int num)
{
	unsigned int i, ret = 0;

	/* Sure, this is order(n^2), but it's usually short, and not
           time critical */
	for (i = 0; i < num; i++) {
		switch (ELF64_R_TYPE(rela[i].r_info)) {
		      case R_IA64_LTOFF22:
		      case R_IA64_LTOFF22X:
		      case R_IA64_LTOFF64I:
		      case R_IA64_LTOFF_FPTR22:
		      case R_IA64_LTOFF_FPTR64I:
		      case R_IA64_LTOFF_FPTR32MSB:
		      case R_IA64_LTOFF_FPTR32LSB:
		      case R_IA64_LTOFF_FPTR64MSB:
		      case R_IA64_LTOFF_FPTR64LSB:
			if (!duplicate_reloc(rela, i))
				ret++;
			break;
		}
	}
	return ret;
}

/* Count how many PLT entries we may need */
static unsigned int
count_plts (const Elf64_Rela *rela, unsigned int num)
{
	unsigned int i, ret = 0;

	/* Sure, this is order(n^2), but it's usually short, and not
           time critical */
	for (i = 0; i < num; i++) {
		switch (ELF64_R_TYPE(rela[i].r_info)) {
		      case R_IA64_PCREL21B:
		      case R_IA64_PLTOFF22:
		      case R_IA64_PLTOFF64I:
		      case R_IA64_PLTOFF64MSB:
		      case R_IA64_PLTOFF64LSB:
		      case R_IA64_IPLTMSB:
		      case R_IA64_IPLTLSB:
			if (!duplicate_reloc(rela, i))
				ret++;
			break;
		}
	}
	return ret;
}

/* We need to create an function-descriptors for any internal function
   which is referenced. */
static unsigned int
count_fdescs (const Elf64_Rela *rela, unsigned int num)
{
	unsigned int i, ret = 0;

	/* Sure, this is order(n^2), but it's usually short, and not time critical.  */
	for (i = 0; i < num; i++) {
		switch (ELF64_R_TYPE(rela[i].r_info)) {
		      case R_IA64_FPTR64I:
		      case R_IA64_FPTR32LSB:
		      case R_IA64_FPTR32MSB:
		      case R_IA64_FPTR64LSB:
		      case R_IA64_FPTR64MSB:
		      case R_IA64_LTOFF_FPTR22:
		      case R_IA64_LTOFF_FPTR32LSB:
		      case R_IA64_LTOFF_FPTR32MSB:
		      case R_IA64_LTOFF_FPTR64I:
		      case R_IA64_LTOFF_FPTR64LSB:
		      case R_IA64_LTOFF_FPTR64MSB:
		      case R_IA64_IPLTMSB:
		      case R_IA64_IPLTLSB:
			/*
			 * Jumps to static functions sometimes go straight to their
			 * offset.  Of course, that may not be possible if the jump is
			 * from init -> core or vice. versa, so we need to generate an
			 * FDESC (and PLT etc) for that.
			 */
		      case R_IA64_PCREL21B:
			if (!duplicate_reloc(rela, i))
				ret++;
			break;
		}
	}
	return ret;
}

int
module_frob_arch_sections (Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, char *secstrings,
			   struct module *mod)
{
	unsigned long core_plts = 0, init_plts = 0, gots = 0, fdescs = 0;
	Elf64_Shdr *s, *sechdrs_end = sechdrs + ehdr->e_shnum;

	/*
	 * To store the PLTs and function-descriptors, we expand the .text section for
	 * core module-code and the .init.text section for initialization code.
	 */
	for (s = sechdrs; s < sechdrs_end; ++s)
		if (strcmp(".core.plt", secstrings + s->sh_name) == 0)
			mod->arch.core_plt = s;
		else if (strcmp(".init.plt", secstrings + s->sh_name) == 0)
			mod->arch.init_plt = s;
		else if (strcmp(".got", secstrings + s->sh_name) == 0)
			mod->arch.got = s;
		else if (strcmp(".opd", secstrings + s->sh_name) == 0)
			mod->arch.opd = s;
		else if (strcmp(".IA_64.unwind", secstrings + s->sh_name) == 0)
			mod->arch.unwind = s;

	if (!mod->arch.core_plt || !mod->arch.init_plt || !mod->arch.got || !mod->arch.opd) {
		printk(KERN_ERR "%s: sections missing\n", mod->name);
		return -ENOEXEC;
	}

	/* GOT and PLTs can occur in any relocated section... */
	for (s = sechdrs + 1; s < sechdrs_end; ++s) {
		const Elf64_Rela *rels = (void *)ehdr + s->sh_offset;
		unsigned long numrels = s->sh_size/sizeof(Elf64_Rela);

		if (s->sh_type != SHT_RELA)
			continue;

		gots += count_gots(rels, numrels);
		fdescs += count_fdescs(rels, numrels);
		if (strstr(secstrings + s->sh_name, ".init"))
			init_plts += count_plts(rels, numrels);
		else
			core_plts += count_plts(rels, numrels);
	}

	mod->arch.core_plt->sh_type = SHT_NOBITS;
	mod->arch.core_plt->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
	mod->arch.core_plt->sh_addralign = 16;
	mod->arch.core_plt->sh_size = core_plts * sizeof(struct plt_entry);
	mod->arch.init_plt->sh_type = SHT_NOBITS;
	mod->arch.init_plt->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
	mod->arch.init_plt->sh_addralign = 16;
	mod->arch.init_plt->sh_size = init_plts * sizeof(struct plt_entry);
	mod->arch.got->sh_type = SHT_NOBITS;
	mod->arch.got->sh_flags = ARCH_SHF_SMALL | SHF_ALLOC;
	mod->arch.got->sh_addralign = 8;
	mod->arch.got->sh_size = gots * sizeof(struct got_entry);
	mod->arch.opd->sh_type = SHT_NOBITS;
	mod->arch.opd->sh_flags = SHF_ALLOC;
	mod->arch.opd->sh_addralign = 8;
	mod->arch.opd->sh_size = fdescs * sizeof(struct fdesc);
	DEBUGP("%s: core.plt=%lx, init.plt=%lx, got=%lx, fdesc=%lx\n",
	       __func__, mod->arch.core_plt->sh_size, mod->arch.init_plt->sh_size,
	       mod->arch.got->sh_size, mod->arch.opd->sh_size);
	return 0;
}

static inline int
in_init (const struct module *mod, uint64_t addr)
{
	return addr - (uint64_t) mod->module_init < mod->init_size;
}

static inline int
in_core (const struct module *mod, uint64_t addr)
{
	return addr - (uint64_t) mod->module_core < mod->core_size;
}

static inline int
is_internal (const struct module *mod, uint64_t value)
{
	return in_init(mod, value) || in_core(mod, value);
}

/*
 * Get gp-relative offset for the linkage-table entry of VALUE.
 */
static uint64_t
get_ltoff (struct module *mod, uint64_t value, int *okp)
{
	struct got_entry *got, *e;

	if (!*okp)
		return 0;

	got = (void *) mod->arch.got->sh_addr;
	for (e = got; e < got + mod->arch.next_got_entry; ++e)
		if (e->val == value)
			goto found;

	/* Not enough GOT entries? */
	if (e >= (struct got_entry *) (mod->arch.got->sh_addr + mod->arch.got->sh_size))
		BUG();

	e->val = value;
	++mod->arch.next_got_entry;
  found:
	return (uint64_t) e - mod->arch.gp;
}

static inline int
gp_addressable (struct module *mod, uint64_t value)
{
	return value - mod->arch.gp + MAX_LTOFF/2 < MAX_LTOFF;
}

/* Get PC-relative PLT entry for this value.  Returns 0 on failure. */
static uint64_t
get_plt (struct module *mod, const struct insn *insn, uint64_t value, int *okp)
{
	struct plt_entry *plt, *plt_end;
	uint64_t target_ip, target_gp;

	if (!*okp)
		return 0;

	if (in_init(mod, (uint64_t) insn)) {
		plt = (void *) mod->arch.init_plt->sh_addr;
		plt_end = (void *) plt + mod->arch.init_plt->sh_size;
	} else {
		plt = (void *) mod->arch.core_plt->sh_addr;
		plt_end = (void *) plt + mod->arch.core_plt->sh_size;
	}

	/* "value" is a pointer to a function-descriptor; fetch the target ip/gp from it: */
	target_ip = ((uint64_t *) value)[0];
	target_gp = ((uint64_t *) value)[1];

	/* Look for existing PLT entry. */
	while (plt->bundle[0][0]) {
		if (plt_target(plt) == target_ip)
			goto found;
		if (++plt >= plt_end)
			BUG();
	}
	*plt = ia64_plt_template;
	if (!patch_plt(mod, plt, target_ip, target_gp)) {
		*okp = 0;
		return 0;
	}
#if ARCH_MODULE_DEBUG
	if (plt_target(plt) != target_ip) {
		printk("%s: mistargeted PLT: wanted %lx, got %lx\n",
		       __func__, target_ip, plt_target(plt));
		*okp = 0;
		return 0;
	}
#endif
  found:
	return (uint64_t) plt;
}

/* Get function descriptor for VALUE. */
static uint64_t
get_fdesc (struct module *mod, uint64_t value, int *okp)
{
	struct fdesc *fdesc = (void *) mod->arch.opd->sh_addr;

	if (!*okp)
		return 0;

	if (!value) {
		printk(KERN_ERR "%s: fdesc for zero requested!\n", mod->name);
		return 0;
	}

	if (!is_internal(mod, value))
		/*
		 * If it's not a module-local entry-point, "value" already points to a
		 * function-descriptor.
		 */
		return value;

	/* Look for existing function descriptor. */
	while (fdesc->ip) {
		if (fdesc->ip == value)
			return (uint64_t)fdesc;
		if ((uint64_t) ++fdesc >= mod->arch.opd->sh_addr + mod->arch.opd->sh_size)
			BUG();
	}

	/* Create new one */
	fdesc->ip = value;
	fdesc->gp = mod->arch.gp;
	return (uint64_t) fdesc;
}

static inline int
do_reloc (struct module *mod, uint8_t r_type, Elf64_Sym *sym, uint64_t addend,
	  Elf64_Shdr *sec, void *location)
{
	enum reloc_target_format format = (r_type >> FORMAT_SHIFT) & FORMAT_MASK;
	enum reloc_value_formula formula = (r_type >> VALUE_SHIFT) & VALUE_MASK;
	uint64_t val;
	int ok = 1;

	val = sym->st_value + addend;

	switch (formula) {
	      case RV_SEGREL:	/* segment base is arbitrarily chosen to be 0 for kernel modules */
	      case RV_DIRECT:
		break;

	      case RV_GPREL:	  val -= mod->arch.gp; break;
	      case RV_LTREL:	  val = get_ltoff(mod, val, &ok); break;
	      case RV_PLTREL:	  val = get_plt(mod, location, val, &ok); break;
	      case RV_FPTR:	  val = get_fdesc(mod, val, &ok); break;
	      case RV_SECREL:	  val -= sec->sh_addr; break;
	      case RV_LTREL_FPTR: val = get_ltoff(mod, get_fdesc(mod, val, &ok), &ok); break;

	      case RV_PCREL:
		switch (r_type) {
		      case R_IA64_PCREL21B:
			if ((in_init(mod, val) && in_core(mod, (uint64_t)location)) ||
			    (in_core(mod, val) && in_init(mod, (uint64_t)location))) {
				/*
				 * Init section may have been allocated far away from core,
				 * if the branch won't reach, then allocate a plt for it.
				 */
				uint64_t delta = ((int64_t)val - (int64_t)location) / 16;
				if (delta + (1 << 20) >= (1 << 21)) {
					val = get_fdesc(mod, val, &ok);
					val = get_plt(mod, location, val, &ok);
				}
			} else if (!is_internal(mod, val))
				val = get_plt(mod, location, val, &ok);
			/* FALL THROUGH */
		      default:
			val -= bundle(location);
			break;

		      case R_IA64_PCREL32MSB:
		      case R_IA64_PCREL32LSB:
		      case R_IA64_PCREL64MSB:
		      case R_IA64_PCREL64LSB:
			val -= (uint64_t) location;
			break;

		}
		switch (r_type) {
		      case R_IA64_PCREL60B: format = RF_INSN60; break;
		      case R_IA64_PCREL21B: format = RF_INSN21B; break;
		      case R_IA64_PCREL21M: format = RF_INSN21M; break;
		      case R_IA64_PCREL21F: format = RF_INSN21F; break;
		      default: break;
		}
		break;

	      case RV_BDREL:
		val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
		break;

	      case RV_LTV:
		/* can link-time value relocs happen here?  */
		BUG();
		break;

	      case RV_PCREL2:
		if (r_type == R_IA64_PCREL21BI) {
			if (!is_internal(mod, val)) {
				printk(KERN_ERR "%s: %s reloc against non-local symbol (%lx)\n",
				       __func__, reloc_name[r_type], val);
				return -ENOEXEC;
			}
			format = RF_INSN21B;
		}
		val -= bundle(location);
		break;

	      case RV_SPECIAL:
		switch (r_type) {
		      case R_IA64_IPLTMSB:
		      case R_IA64_IPLTLSB:
			val = get_fdesc(mod, get_plt(mod, location, val, &ok), &ok);
			format = RF_64LSB;
			if (r_type == R_IA64_IPLTMSB)
				format = RF_64MSB;
			break;

		      case R_IA64_SUB:
			val = addend - sym->st_value;
			format = RF_INSN64;
			break;

		      case R_IA64_LTOFF22X:
			if (gp_addressable(mod, val))
				val -= mod->arch.gp;
			else
				val = get_ltoff(mod, val, &ok);
			format = RF_INSN22;
			break;

		      case R_IA64_LDXMOV:
			if (gp_addressable(mod, val)) {
				/* turn "ld8" into "mov": */
				DEBUGP("%s: patching ld8 at %p to mov\n", __func__, location);
				ia64_patch((u64) location, 0x1fff80fe000UL, 0x10000000000UL);
			}
			return 0;

		      default:
			if (reloc_name[r_type])
				printk(KERN_ERR "%s: special reloc %s not supported",
				       mod->name, reloc_name[r_type]);
			else
				printk(KERN_ERR "%s: unknown special reloc %x\n",
				       mod->name, r_type);
			return -ENOEXEC;
		}
		break;

	      case RV_TPREL:
	      case RV_LTREL_TPREL:
	      case RV_DTPMOD:
	      case RV_LTREL_DTPMOD:
	      case RV_DTPREL:
	      case RV_LTREL_DTPREL:
		printk(KERN_ERR "%s: %s reloc not supported\n",
		       mod->name, reloc_name[r_type] ? reloc_name[r_type] : "?");
		return -ENOEXEC;

	      default:
		printk(KERN_ERR "%s: unknown reloc %x\n", mod->name, r_type);
		return -ENOEXEC;
	}

	if (!ok)
		return -ENOEXEC;

	DEBUGP("%s: [%p]<-%016lx = %s(%lx)\n", __func__, location, val,
	       reloc_name[r_type] ? reloc_name[r_type] : "?", sym->st_value + addend);

	switch (format) {
	      case RF_INSN21B:	ok = apply_imm21b(mod, location, (int64_t) val / 16); break;
	      case RF_INSN22:	ok = apply_imm22(mod, location, val); break;
	      case RF_INSN64:	ok = apply_imm64(mod, location, val); break;
	      case RF_INSN60:	ok = apply_imm60(mod, location, (int64_t) val / 16); break;
	      case RF_32LSB:	put_unaligned(val, (uint32_t *) location); break;
	      case RF_64LSB:	put_unaligned(val, (uint64_t *) location); break;
	      case RF_32MSB:	/* ia64 Linux is little-endian... */
	      case RF_64MSB:	/* ia64 Linux is little-endian... */
	      case RF_INSN14:	/* must be within-module, i.e., resolved by "ld -r" */
	      case RF_INSN21M:	/* must be within-module, i.e., resolved by "ld -r" */
	      case RF_INSN21F:	/* must be within-module, i.e., resolved by "ld -r" */
		printk(KERN_ERR "%s: format %u needed by %s reloc is not supported\n",
		       mod->name, format, reloc_name[r_type] ? reloc_name[r_type] : "?");
		return -ENOEXEC;

	      default:
		printk(KERN_ERR "%s: relocation %s resulted in unknown format %u\n",
		       mod->name, reloc_name[r_type] ? reloc_name[r_type] : "?", format);
		return -ENOEXEC;
	}
	return ok ? 0 : -ENOEXEC;
}

int
apply_relocate_add (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symindex,
		    unsigned int relsec, struct module *mod)
{
	unsigned int i, n = sechdrs[relsec].sh_size / sizeof(Elf64_Rela);
	Elf64_Rela *rela = (void *) sechdrs[relsec].sh_addr;
	Elf64_Shdr *target_sec;
	int ret;

	DEBUGP("%s: applying section %u (%u relocs) to %u\n", __func__,
	       relsec, n, sechdrs[relsec].sh_info);

	target_sec = sechdrs + sechdrs[relsec].sh_info;

	if (target_sec->sh_entsize == ~0UL)
		/*
		 * If target section wasn't allocated, we don't need to relocate it.
		 * Happens, e.g., for debug sections.
		 */
		return 0;

	if (!mod->arch.gp) {
		/*
		 * XXX Should have an arch-hook for running this after final section
		 *     addresses have been selected...
		 */
		uint64_t gp;
		if (mod->core_size > MAX_LTOFF)
			/*
			 * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
			 * at the end of the module.
			 */
			gp = mod->core_size - MAX_LTOFF / 2;
		else
			gp = mod->core_size / 2;
		gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
		mod->arch.gp = gp;
		DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp);
	}

	for (i = 0; i < n; i++) {
		ret = do_reloc(mod, ELF64_R_TYPE(rela[i].r_info),
			       ((Elf64_Sym *) sechdrs[symindex].sh_addr
				+ ELF64_R_SYM(rela[i].r_info)),
			       rela[i].r_addend, target_sec,
			       (void *) target_sec->sh_addr + rela[i].r_offset);
		if (ret < 0)
			return ret;
	}
	return 0;
}

int
apply_relocate (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symindex,
		unsigned int relsec, struct module *mod)
{
	printk(KERN_ERR "module %s: REL relocs in section %u unsupported\n", mod->name, relsec);
	return -ENOEXEC;
}

/*
 * Modules contain a single unwind table which covers both the core and the init text
 * sections but since the two are not contiguous, we need to split this table up such that
 * we can register (and unregister) each "segment" separately.  Fortunately, this sounds
 * more complicated than it really is.
 */
static void
register_unwind_table (struct module *mod)
{
	struct unw_table_entry *start = (void *) mod->arch.unwind->sh_addr;
	struct unw_table_entry *end = start + mod->arch.unwind->sh_size / sizeof (*start);
	struct unw_table_entry tmp, *e1, *e2, *core, *init;
	unsigned long num_init = 0, num_core = 0;

	/* First, count how many init and core unwind-table entries there are.  */
	for (e1 = start; e1 < end; ++e1)
		if (in_init(mod, e1->start_offset))
			++num_init;
		else
			++num_core;
	/*
	 * Second, sort the table such that all unwind-table entries for the init and core
	 * text sections are nicely separated.  We do this with a stupid bubble sort
	 * (unwind tables don't get ridiculously huge).
	 */
	for (e1 = start; e1 < end; ++e1) {
		for (e2 = e1 + 1; e2 < end; ++e2) {
			if (e2->start_offset < e1->start_offset) {
				tmp = *e1;
				*e1 = *e2;
				*e2 = tmp;
			}
		}
	}
	/*
	 * Third, locate the init and core segments in the unwind table:
	 */
	if (in_init(mod, start->start_offset)) {
		init = start;
		core = start + num_init;
	} else {
		core = start;
		init = start + num_core;
	}

	DEBUGP("%s: name=%s, gp=%lx, num_init=%lu, num_core=%lu\n", __func__,
	       mod->name, mod->arch.gp, num_init, num_core);

	/*
	 * Fourth, register both tables (if not empty).
	 */
	if (num_core > 0) {
		mod->arch.core_unw_table = unw_add_unwind_table(mod->name, 0, mod->arch.gp,
								core, core + num_core);
		DEBUGP("%s:  core: handle=%p [%p-%p)\n", __func__,
		       mod->arch.core_unw_table, core, core + num_core);
	}
	if (num_init > 0) {
		mod->arch.init_unw_table = unw_add_unwind_table(mod->name, 0, mod->arch.gp,
								init, init + num_init);
		DEBUGP("%s:  init: handle=%p [%p-%p)\n", __func__,
		       mod->arch.init_unw_table, init, init + num_init);
	}
}

int
module_finalize (const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *mod)
{
	DEBUGP("%s: init: entry=%p\n", __func__, mod->init);
	if (mod->arch.unwind)
		register_unwind_table(mod);
	return 0;
}

void
module_arch_cleanup (struct module *mod)
{
	if (mod->arch.init_unw_table)
		unw_remove_unwind_table(mod->arch.init_unw_table);
	if (mod->arch.core_unw_table)
		unw_remove_unwind_table(mod->arch.core_unw_table);
}
