/*
* 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.
*
* irixelf.c: Code to load IRIX ELF executables conforming to the MIPS ABI.
* Based off of work by Eric Youngdale.
*
* Copyright (C) 1993 - 1994 Eric Youngdale <ericy@cais.com>
* Copyright (C) 1996 - 2004 David S. Miller <dm@engr.sgi.com>
* Copyright (C) 2004 - 2005 Steven J. Hill <sjhill@realitydiluted.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/a.out.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/signal.h>
#include <linux/binfmts.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/elfcore.h>
#include <linux/smp_lock.h>
#include <asm/mipsregs.h>
#include <asm/namei.h>
#include <asm/prctl.h>
#include <asm/uaccess.h>
#define DLINFO_ITEMS 12
#include <linux/elf.h>
#undef DEBUG
static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs);
static int load_irix_library(struct file *);
static int irix_core_dump(long signr, struct pt_regs * regs,
struct file *file);
static struct linux_binfmt irix_format = {
NULL, THIS_MODULE, load_irix_binary, load_irix_library,
irix_core_dump, PAGE_SIZE
};
#ifndef elf_addr_t
#define elf_addr_t unsigned long
#endif
#ifdef DEBUG
/* Debugging routines. */
static char *get_elf_p_type(Elf32_Word p_type)
{
int i = (int) p_type;
switch(i) {
case PT_NULL: return("PT_NULL"); break;
case PT_LOAD: return("PT_LOAD"); break;
case PT_DYNAMIC: return("PT_DYNAMIC"); break;
case PT_INTERP: return("PT_INTERP"); break;
case PT_NOTE: return("PT_NOTE"); break;
case PT_SHLIB: return("PT_SHLIB"); break;
case PT_PHDR: return("PT_PHDR"); break;
case PT_LOPROC: return("PT_LOPROC/REGINFO"); break;
case PT_HIPROC: return("PT_HIPROC"); break;
default: return("PT_BOGUS"); break;
}
}
static void print_elfhdr(struct elfhdr *ehp)
{
int i;
printk("ELFHDR: e_ident<");
for(i = 0; i < (EI_NIDENT - 1); i++) printk("%x ", ehp->e_ident[i]);
printk("%x>\n", ehp->e_ident[i]);
printk(" e_type[%04x] e_machine[%04x] e_version[%08lx]\n",
(unsigned short) ehp->e_type, (unsigned short) ehp->e_machine,
(unsigned long) ehp->e_version);
printk(" e_entry[%08lx] e_phoff[%08lx] e_shoff[%08lx] "
"e_flags[%08lx]\n",
(unsigned long) ehp->e_entry, (unsigned long) ehp->e_phoff,
(unsigned long) ehp->e_shoff, (unsigned long) ehp->e_flags);
printk(" e_ehsize[%04x] e_phentsize[%04x] e_phnum[%04x]\n",
(unsigned short) ehp->e_ehsize, (unsigned short) ehp->e_phentsize,
(unsigned short) ehp->e_phnum);
printk(" e_shentsize[%04x] e_shnum[%04x] e_shstrndx[%04x]\n",
(unsigned short) ehp->e_shentsize, (unsigned short) ehp->e_shnum,
(unsigned short) ehp->e_shstrndx);
}
static void print_phdr(int i, struct elf_phdr *ep)
{
printk("PHDR[%d]: p_type[%s] p_offset[%08lx] p_vaddr[%08lx] "
"p_paddr[%08lx]\n", i, get_elf_p_type(ep->p_type),
(unsigned long) ep->p_offset, (unsigned long) ep->p_vaddr,
(unsigned long) ep->p_paddr);
printk(" p_filesz[%08lx] p_memsz[%08lx] p_flags[%08lx] "
"p_align[%08lx]\n", (unsigned long) ep->p_filesz,
(unsigned long) ep-><
|