/*
 * linux/fs/binfmt_som.c
 *
 * These are the functions used to load SOM format executables as used
 * by HP-UX.  
 *
 * Copyright 1999 Matthew Wilcox <willy@bofh.ai>
 * based on binfmt_elf which is
 * Copyright 1993, 1994: Eric Youngdale (ericy@cais.com).
 */

#include <linux/module.h>

#include <linux/fs.h>
#include <linux/stat.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/binfmts.h>
#include <linux/som.h>
#include <linux/string.h>
#include <linux/file.h>
#include <linux/fcntl.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/shm.h>
#include <linux/personality.h>
#include <linux/init.h>

#include <asm/uaccess.h>
#include <asm/pgtable.h>


#include <linux/elf.h>

static int load_som_binary(struct linux_binprm * bprm, struct pt_regs * regs);
static int load_som_library(struct file *);

/*
 * If we don't support core dumping, then supply a NULL so we
 * don't even try.
 */
#if 0
static int som_core_dump(long signr, struct pt_regs *regs, unsigned long limit);
#else
#define som_core_dump	NULL
#endif

#define SOM_PAGESTART(_v) ((_v) & ~(unsigned long)(SOM_PAGESIZE-1))
#define SOM_PAGEOFFSET(_v) ((_v) & (SOM_PAGESIZE-1))
#define SOM_PAGEALIGN(_v) (((_v) + SOM_PAGESIZE - 1) & ~(SOM_PAGESIZE - 1))

static struct linux_binfmt som_format = {
	.module		= THIS_MODULE,
	.load_binary	= load_som_binary,
	.load_shlib	= load_som_library,
	.core_dump	= som_core_dump,
	.min_coredump	= SOM_PAGESIZE
};

/*
 * create_som_tables() parses the env- and arg-strings in new user
 * memory and creates the pointer tables from them, and puts their
 * addresses on the "stack", returning the new stack pointer value.
 */
static void create_som_tables(struct linux_binprm *bprm)
{
	char **argv, **envp;
	int argc = bprm->argc;
	int envc = bprm->envc;
	unsigned long p;
	unsigned long *sp;

	/* Word-align the stack pointer */
	sp = (unsigned long *)((bprm->p + 3) & ~3);

	envp = (char **) sp;
	sp += envc + 1;
	argv = (char **) sp;
	sp += argc + 1;

	__put_user((unsigned long) envp,++sp);
	__put_user((unsigned long) argv,++sp);

	__put_user(argc, ++sp);

	bprm->p = (unsigned long) sp;

	p = current->mm->arg_start;
	while (argc-- > 0) {
		__put_user((char *)p,argv++);
		p += strlen_user((char *)p);
	}
	__put_user(NULL, argv);
	current->mm->arg_end = current->mm->env_start = p;
	while (envc-- > 0) {
		__put_user((char *)p,envp++);
		p += strlen_user((char *)p);
	}
	__put_user(NULL, envp);
	current->mm->env_end = p;
}

static int check_som_header(struct som_hdr *som_ex)
{
	int *buf = (int *)som_ex;
	int i, ck;

	if (som_ex->system_id != SOM_SID_PARISC_1_0 &&
	    som_ex->system_id != SOM_SID_PARISC_1_1 &&
	    som_ex->system_id != SOM_SID_PARISC_2_0)
		return -ENOEXEC;

	if (som_ex->a_magic != SOM_EXEC_NONSHARE &&
	    som_ex->a_magic != SOM_EXEC_SHARE &&
	    som_ex->a_magic != SOM_EXEC_DEMAND)
		return -ENOEXEC;

	if (som_ex->version_id != SOM_ID_OLD &&
	    som_ex->version_id != SOM_ID_NEW)
		return -ENOEXEC;

	ck = 0;
	for (i=0; i<32; i++)
		ck ^= buf[i];
	if (ck != 0)
		return -ENOEXEC;

	return 0;
}

static int map_som_binary(struct file *file,
		const struct som_exec_auxhdr *hpuxhdr)
{
	unsigned long code_start, code_size, data_start, data_size;
	unsigned long bss_start, som_brk;
	int retval;
	int prot = PROT_READ | PROT_EXEC;
	int flags = MAP_FIXED|MAP_PRIVATE|MAP_DENYWRITE|MAP_EXECUTABLE;

	mm_segment_t old_fs = get_fs();
	set_fs(get_ds());

	code_start = SOM_PAGESTART(hpuxhdr->exec_tmem);
	code_size = SOM_PAGEALIGN(hpuxhdr->exec_tsize);
	current->mm->start_code = code_start;
	current->mm->end_code = code_start + code_size;
	down_write(&current->mm->mmap_sem);
	retval = do_mmap(file, code_start, code_size, prot,
			flags, SOM_PAGESTART(hpuxhdr->exec_tfile));
	up_write(&current->mm->mmap_sem);
	if (retval < 0 && retval > -1024)
		goto out;

	data_start = SOM_PAGESTART(hpuxhdr->exec_dmem);
	data_size = SOM_PAGEALIGN(hpuxhdr->exec_dsize);
	current->mm->start_data = data_start;
	current->mm->end_data = bss_start = data_start + data_size;
	down_write(&current->mm->mmap_sem);
	retval = do_mmap(file, data_start, data_size,
			prot | PROT_WRITE, flags,
			SOM_PAGESTART(hpuxhdr->exec_dfile));
	up_write(&current->mm->mmap_sem);
	if (retval < 0 && retval > -1024)
		goto out;

	som_brk = bss_start + SOM_PAGEALIGN(hpuxhdr->exec_bsize);
	current->mm->start_brk = current->mm->brk = som_brk;
	down_write(&current->mm->mmap_sem);
	retval = do_mmap(NULL, bss_start, som_brk - bss_start,
			prot | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, 0);
	up_write(&current->mm->mmap_sem);
	if (retval > 0 || retval < -1024)
		retval = 0;
out:
	set_fs(old_fs);
	return retval;
}


/*
 * These are the functions used to load SOM executables and shared
 * libraries.  There is no binary dependent code anywhere else.
 */

static int
load_som_binary(struct linux_binprm * bprm, struct pt_regs * regs)
{
	int som_exec_fileno;
	int retval;
	unsigned int size;
	unsigned long som_entry;
	struct som_hdr *som_ex;
	struct som_exec_auxhdr *hpuxhdr;
	struct files_struct *files;

	/* Get the exec-header */
	som_ex = (struct som_hdr *) bprm->buf;

	retval = check_som_header(som_ex);
	if (retval != 0)
		goto out;

	/* Now read in the auxiliary header information */

	retval = -ENOMEM;
	size = som_ex->aux_header_size;
	if (size > SOM_PAGESIZE)
		goto out;
	hpuxhdr = kmalloc(size, GFP_KERNEL);
	if (!hpuxhdr)
		goto out;

	retval = kernel_read(bprm->file, som_ex->aux_header_location,
			(char *) hpuxhdr, size);
	if (retval != size) {
		if (retval >= 0)
			retval = -EIO;
		goto out_free;
	}

	files = current->files; /* Refcounted so ok */
	retval = unshare_files();
	if (retval < 0)
		goto out_free;
	if (files == current->files) {
		put_files_struct(files);
		files = NULL;
	}

	retval = get_unused_fd();
	if (retval < 0)
		goto out_free;
	get_file(bprm->file);
	fd_install(som_exec_fileno = retval, bprm->file);

	/* Flush all traces of the currently running executable */
	retval = flush_old_exec(bprm);
	if (retval)
		goto out_free;

	/* OK, This is the point of no return */
	current->flags &= ~PF_FORKNOEXEC;
	current->personality = PER_HPUX;

	/* Set the task size for HP-UX processes such that
	 * the gateway page is outside the address space.
	 * This can be fixed later, but for now, this is much
	 * easier.
	 */

	current->thread.task_size = 0xc0000000;

	/* Set map base to allow enough room for hp-ux heap growth */

	current->thread.map_base = 0x80000000;

	retval = map_som_binary(bprm->file, hpuxhdr);
	if (retval < 0)
		goto out_free;

	som_entry = hpuxhdr->exec_entry;
	kfree(hpuxhdr);

	set_binfmt(&som_format);
	compute_creds(bprm);
	setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT);

	create_som_tables(bprm);

	current->mm->start_stack = bprm->p;

#if 0
	printk("(start_brk) %08lx\n" , (unsigned long) current->mm->start_brk);
	printk("(end_code) %08lx\n" , (unsigned long) current->mm->end_code);
	printk("(start_code) %08lx\n" , (unsigned long) current->mm->start_code);
	printk("(end_data) %08lx\n" , (unsigned long) current->mm->end_data);
	printk("(start_stack) %08lx\n" , (unsigned long) current->mm->start_stack);
	printk("(brk) %08lx\n" , (unsigned long) current->mm->brk);
#endif

	map_hpux_gateway_page(current,current->mm);

	start_thread_som(regs, som_entry, bprm->p);
	if (current->ptrace & PT_PTRACED)
		send_sig(SIGTRAP, current, 0);
	return 0;

	/* error cleanup */
out_free:
	kfree(hpuxhdr);
out:
	return retval;
}

static int load_som_library(struct file *f)
{
/* No lib support in SOM yet.  gizza chance.. */
	return -ENOEXEC;
}
	/* Install the SOM loader.
	 * N.B. We *rely* on the table being the right size with the
	 * right number of free slots...
	 */

static int __init init_som_binfmt(void)
{
	return register_binfmt(&som_format);
}

static void __exit exit_som_binfmt(void)
{
	/* Remove the SOM loader. */
	unregister_binfmt(&som_format);
}

core_initcall(init_som_binfmt);
module_exit(exit_som_binfmt);
