/*
 * arch/v850/kernel/module.c -- Architecture-specific module functions
 *
 *  Copyright (C) 2002  NEC Corporation
 *  Copyright (C) 2002  Miles Bader <miles@gnu.org>
 *  Copyright (C) 2001  Rusty Russell
 *
 * This file is subject to the terms and conditions of the GNU General
 * Public License.  See the file COPYING in the main directory of this
 * archive for more details.
 *
 * Written by Miles Bader <miles@gnu.org>
 *
 * Derived in part from arch/ppc/kernel/module.c
 */

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

#if 0
#define DEBUGP printk
#else
#define DEBUGP(fmt , ...)
#endif

void *module_alloc (unsigned long size)
{
	return size == 0 ? 0 : vmalloc (size);
}

void module_free (struct module *mod, void *module_region)
{
	vfree (module_region);
	/* FIXME: If module_region == mod->init_region, trim exception
           table entries. */
}

int module_finalize (const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
		     struct module *mod)
{
	return 0;
}

/* Count how many different relocations (different symbol, different
   addend) */
static unsigned int count_relocs(const Elf32_Rela *rela, unsigned int num)
{
	unsigned int i, j, ret = 0;

	/* Sure, this is order(n^2), but it's usually short, and not
           time critical */
	for (i = 0; i < num; i++) {
		for (j = 0; j < i; j++) {
			/* If this addend appeared before, it's
                           already been counted */
			if (ELF32_R_SYM(rela[i].r_info)
			    == ELF32_R_SYM(rela[j].r_info)
			    && rela[i].r_addend == rela[j].r_addend)
				break;
		}
		if (j == i) ret++;
	}
	return ret;
}

/* Get the potential trampolines size required of the init and
   non-init sections */
static unsigned long get_plt_size(const Elf32_Ehdr *hdr,
				  const Elf32_Shdr *sechdrs,
				  const char *secstrings,
				  int is_init)
{
	unsigned long ret = 0;
	unsigned i;

	/* Everything marked ALLOC (this includes the exported
           symbols) */
	for (i = 1; i < hdr->e_shnum; i++) {
		/* If it's called *.init*, and we're not init, we're
                   not interested */
		if ((strstr(secstrings + sechdrs[i].sh_name, ".init") != 0)
		    != is_init)
			continue;

		if (sechdrs[i].sh_type == SHT_RELA) {
			DEBUGP("Found relocations in section %u\n", i);
			DEBUGP("Ptr: %p.  Number: %u\n",
			       (void *)hdr + sechdrs[i].sh_offset,
			       sechdrs[i].sh_size / sizeof(Elf32_Rela));
			ret += count_relocs((void *)hdr
					     + sechdrs[i].sh_offset,
					     sechdrs[i].sh_size
					     / sizeof(Elf32_Rela))
				* sizeof(struct v850_plt_entry);
		}
	}

	return ret;
}

long module_core_size (const Elf32_Ehdr *hdr, const Elf32_Shdr *sechdrs,
		       const char *secstrings, struct module *mod)
{
	mod->arch.core_plt_offset = (mod->core_size + 3) & ~3;
	return mod->core_size + get_plt_size (hdr, sechdrs, secstrings, 1);
}

long module_init_size (const Elf32_Ehdr *hdr, const Elf32_Shdr *sechdrs,
		       const char *secstrings, struct module *mod)
{
	mod->arch.init_plt_offset = (mod->init_size + 3) & ~3;
	return mod->init_size + get_plt_size (hdr, sechdrs, secstrings, 1);
}

int apply_relocate (Elf32_Shdr *sechdrs, const char *strtab,
		    unsigned int symindex, unsigned int relsec,
		    struct module *mod)
{
	printk ("Barf\n");
	return -ENOEXEC;
}

/* Set up a trampoline in the PLT to bounce us to the distant function */
static uint32_t do_plt_call(void *location, Elf32_Addr val, struct module *mod)
{
	struct v850_plt_entry *entry;
	/* Instructions used to do the indirect jump.  */
	uint32_t tramp[2];

	/* We have to trash a register, so we assume that any control
	   transfer more than 21-bits away must be a function call
	   (so we can use a call-clobbered register).  */
	tramp[0] = 0x0621 + ((val & 0xffff) << 16);   /* mov sym, r1 ... */
	tramp[1] = ((val >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */

	/* Init, or core PLT? */
	if (location >= mod->module_core
	    && location < mod->module_core + mod->arch.core_plt_offset)
		entry = mod->module_core + mod->arch.core_plt_offset;
	else
		entry = mod->module_init + mod->arch.init_plt_offset;

	/* Find this entry, or if that fails, the next avail. entry */
	while (entry->tramp[0])
		if (entry->tramp[0] == tramp[0] && entry->tramp[1] == tramp[1])
			return (uint32_t)entry;
		else
			entry++;

	entry->tramp[0] = tramp[0];
	entry->tramp[1] = tramp[1];

	return (uint32_t)entry;
}

int apply_relocate_add (Elf32_Shdr *sechdrs, const char *strtab,
			unsigned int symindex, unsigned int relsec,
			struct module *mod)
{
	unsigned int i;
	Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr;

	DEBUGP ("Applying relocate section %u to %u\n", relsec,
		sechdrs[relsec].sh_info);

	for (i = 0; i < sechdrs[relsec].sh_size / sizeof (*rela); i++) {
		/* This is where to make the change */
		uint32_t *loc
			= ((void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
			   + rela[i].r_offset);
		/* This is the symbol it is referring to */
		Elf32_Sym *sym
			= ((Elf32_Sym *)sechdrs[symindex].sh_addr
			   + ELF32_R_SYM (rela[i].r_info));
		uint32_t val = sym->st_value;

		if (! val) {
			printk (KERN_WARNING "%s: Unknown symbol %s\n",
				mod->name, strtab + sym->st_name);
			return -ENOENT;
		}

		val += rela[i].r_addend;

		switch (ELF32_R_TYPE (rela[i].r_info)) {
		case R_V850_32:
			/* We write two shorts instead of a long because even
			   32-bit insns only need half-word alignment, but
			   32-bit data writes need to be long-word aligned.  */
			val += ((uint16_t *)loc)[0];
			val += ((uint16_t *)loc)[1] << 16;
			((uint16_t *)loc)[0] = val & 0xffff;
			((uint16_t *)loc)[1] = (val >> 16) & 0xffff;
			break;

		case R_V850_22_PCREL:
			/* Maybe jump indirectly via a PLT table entry.  */
			if ((int32_t)(val - (uint32_t)loc) > 0x1fffff
			    || (int32_t)(val - (uint32_t)loc) < -0x200000)
				val = do_plt_call (loc, val, mod);

			val -= (uint32_t)loc;

			/* We write two shorts instead of a long because
			   even 32-bit insns only need half-word alignment,
			   but 32-bit data writes need to be long-word
			   aligned.  */
			((uint16_t *)loc)[0] =
				(*(uint16_t *)loc & 0xffc0) /* opcode + reg */
				| ((val >> 16) & 0xffc03f); /* offs high */
			((uint16_t *)loc)[1] =
				(val & 0xffff);		    /* offs low */
			break;

		default:
			printk (KERN_ERR "module %s: Unknown reloc: %u\n",
				mod->name, ELF32_R_TYPE (rela[i].r_info));
			return -ENOEXEC;
		}
	}

	return 0;
}
