/* binfmt_elf_fdpic.c: FDPIC ELF binary format
*
* Copyright (C) 2003, 2004 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
* Derived from binfmt_elf.c
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#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/string.h>
#include <linux/file.h>
#include <linux/fcntl.h>
#include <linux/slab.h>
#include <linux/highmem.h>
#include <linux/personality.h>
#include <linux/ptrace.h>
#include <linux/init.h>
#include <linux/smp_lock.h>
#include <linux/elf.h>
#include <linux/elf-fdpic.h>
#include <linux/elfcore.h>
#include <asm/uaccess.h>
#include <asm/param.h>
#include <asm/pgalloc.h>
typedef char *elf_caddr_t;
#ifndef elf_addr_t
#define elf_addr_t unsigned long
#endif
#if 0
#define kdebug(fmt, ...) printk("FDPIC "fmt"\n" ,##__VA_ARGS__ )
#else
#define kdebug(fmt, ...) do {} while(0)
#endif
MODULE_LICENSE("GPL");
static int load_elf_fdpic_binary(struct linux_binprm *bprm, struct pt_regs *regs);
//static int load_elf_fdpic_library(struct file *);
static int elf_fdpic_fetch_phdrs(struct elf_fdpic_params *params, struct file *file);
static int elf_fdpic_map_file(struct elf_fdpic_params *params,
struct file *file,
struct mm_struct *mm,
const char *what);
static int create_elf_fdpic_tables(struct linux_binprm *bprm,
struct mm_struct *mm,
struct elf_fdpic_params *exec_params,
struct elf_fdpic_params *interp_params);
#ifndef CONFIG_MMU
static int elf_fdpic_transfer_args_to_stack(struct linux_binprm *bprm, unsigned long *_sp);
static int elf_fdpic_map_file_constdisp_on_uclinux(struct elf_fdpic_params *params,
struct file *file,
struct mm_struct *mm);
#endif
static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
struct file *file,
struct mm_struct *mm);
static struct linux_binfmt elf_fdpic_format = {
.module = THIS_MODULE,
.load_binary = load_elf_fdpic_binary,
// .load_shlib = load_elf_fdpic_library,
// .core_dump = elf_fdpic_core_dump,
.min_coredump = ELF_EXEC_PAGESIZE,
};
static int __init init_elf_fdpic_binfmt(void) { return register_binfmt(&elf_fdpic_format); }
static void __exit exit_elf_fdpic_binfmt(void) { unregister_binfmt(&elf_fdpic_format); }
module_init(init_elf_fdpic_binfmt)
module_exit(exit_elf_fdpic_binfmt)
static int is_elf_fdpic(struct elfhdr *hdr, struct file *file)
{
if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0)
return 0;
if (hdr->e_type != ET_EXEC && hdr->e_type != ET_DYN)
return 0;
if (!elf_check_arch(hdr) || !elf_check_fdpic(hdr))
return 0;
if (!file->f_op || !file->f_op->mmap)
return 0;
return 1;
}
/*****************************************************************************/
/*
* read the program headers table into memory
*/
static int elf_fdpic_fetch_phdrs(struct elf_fdpic_params *params, struct file *file)
{
struct elf32_phdr *phdr;
unsigned long size;
int retval, loop;
if (params->hdr.e_phentsize != sizeof(struct elf_phdr))
return -ENOMEM;
if (params->hdr.e_phnum > 65536U / sizeof(struct elf_phdr))
return -ENOMEM;
size = params->hdr.e_phnum * sizeof(struct elf_phdr);
params->phdrs = kmalloc(size, GFP_KERNEL);
if (!params->phdrs)
return -ENOMEM;
retval = kernel_read(file, params->hdr.e_phoff, (char *) params->phdrs, size);
if