patch-2.3.48 linux/arch/mips/kernel/irixelf.c
Next file: linux/arch/mips/kernel/irixinv.c
Previous file: linux/arch/mips/kernel/ipc.c
Back to the patch index
Back to the overall index
- Lines: 399
- Date:
Sat Feb 26 20:33:02 2000
- Orig file:
v2.3.47/linux/arch/mips/kernel/irixelf.c
- Orig date:
Sun Jul 25 13:45:25 1999
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/irixelf.c linux/arch/mips/kernel/irixelf.c
@@ -1,4 +1,4 @@
-/* $Id: irixelf.c,v 1.17 1999/06/17 13:25:45 ralf Exp $
+/* $Id: irixelf.c,v 1.24 2000/02/04 07:40:23 ralf Exp $
*
* irixelf.c: Code to load IRIX ELF executables which conform to
* the MIPS ABI.
@@ -22,6 +22,7 @@
#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/malloc.h>
@@ -30,7 +31,7 @@
#include <linux/elfcore.h>
#include <asm/uaccess.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/mipsregs.h>
#include <asm/prctl.h>
@@ -44,17 +45,13 @@
static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs);
static int load_irix_library(int fd);
-static int irix_core_dump(long signr, struct pt_regs * regs);
+static int irix_core_dump(long signr, struct pt_regs * regs,
+ struct file *file);
extern int dump_fpu (elf_fpregset_t *);
static struct linux_binfmt irix_format = {
- NULL,
-#ifndef MODULE
- NULL,
-#else
- &__this_module.usecount,
-#endif
- load_irix_binary, load_irix_library, irix_core_dump, PAGE_SIZE
+ NULL, THIS_MODULE, load_irix_binary, load_irix_library,
+ irix_core_dump, PAGE_SIZE
};
#ifndef elf_addr_t
@@ -263,8 +260,8 @@
if((interp_elf_ex->e_type != ET_EXEC &&
interp_elf_ex->e_type != ET_DYN) ||
!elf_check_arch(interp_elf_ex->e_machine) ||
- (!interpreter_dentry->d_inode->i_op ||
- !interpreter_dentry->d_inode->i_op->default_file_ops->mmap)) {
+ (!interpreter_dentry->d_inode->i_fop ||
+ !interpreter_dentry->d_inode->i_fop->mmap)) {
printk("IRIX interp has bad e_type %d\n", interp_elf_ex->e_type);
return 0xffffffff;
}
@@ -407,16 +404,14 @@
/* Check sanity of IRIX elf executable header. */
static int verify_binary(struct elfhdr *ehp, struct linux_binprm *bprm)
{
- if (ehp->e_ident[0] != 0x7f || strncmp(&ehp->e_ident[1], "ELF", 3)) {
- return -ENOEXEC;
- }
+ if (memcmp(ehp->e_ident, ELFMAG, SELFMAG) != 0)
+ return -ENOEXEC;
/* First of all, some simple consistency checks */
if((ehp->e_type != ET_EXEC && ehp->e_type != ET_DYN) ||
!elf_check_arch(ehp->e_machine) ||
- (!bprm->dentry->d_inode->i_op ||
- !bprm->dentry->d_inode->i_op->default_file_ops ||
- !bprm->dentry->d_inode->i_op->default_file_ops->mmap)) {
+ (!bprm->dentry->d_inode->i_fop ||
+ !bprm->dentry->d_inode->i_fop->mmap)) {
return -ENOEXEC;
}
@@ -498,7 +493,7 @@
static inline int verify_irix_interpreter(struct elfhdr *ihp)
{
- if(ihp->e_ident[0] != 0x7f || strncmp(&ihp->e_ident[1], "ELF", 3))
+ if (memcmp(ihp->e_ident, ELFMAG, SELFMAG) != 0)
return -ELIBBAD;
return 0;
}
@@ -625,9 +620,10 @@
has_interp = has_ephdr = 0;
elf_ihdr = elf_ephdr = 0;
elf_ex = *((struct elfhdr *) bprm->buf);
-
- if(verify_binary(&elf_ex, bprm))
- return -ENOEXEC;
+ retval = -ENOEXEC;
+
+ if (verify_binary(&elf_ex, bprm))
+ goto out;
#ifdef DEBUG_ELF
print_elfhdr(&elf_ex);
@@ -635,15 +631,19 @@
/* Now read in all of the header information */
size = elf_ex.e_phentsize * elf_ex.e_phnum;
+ if (size > 65536)
+ goto out;
elf_phdata = (struct elf_phdr *) kmalloc(size, GFP_KERNEL);
- if (elf_phdata == NULL)
- return -ENOMEM;
-
+ if (elf_phdata == NULL) {
+ retval = -ENOMEM;
+ goto out;
+ }
+
retval = read_exec(bprm->dentry, elf_ex.e_phoff,
(char *) elf_phdata, size, 1);
if (retval < 0)
- goto out_phdata;
-
+ goto out_free_ph;
+
#ifdef DEBUG_ELF
dump_phdrs(elf_phdata, elf_ex.e_phnum);
#endif
@@ -669,39 +669,39 @@
elf_brk = 0;
retval = open_dentry(bprm->dentry, O_RDONLY);
if (retval < 0)
- goto out_phdata;
+ goto out_free_ph;
file = fget(elf_exec_fileno = retval);
-
+
elf_stack = 0xffffffff;
elf_interpreter = NULL;
start_code = 0xffffffff;
end_code = 0;
end_data = 0;
-
+
retval = look_for_irix_interpreter(&elf_interpreter,
&interpreter_dentry,
&interp_elf_ex, elf_phdata, bprm,
elf_ex.e_phnum);
if(retval)
- goto out_file;
-
+ goto out_free_file;
+
if(elf_interpreter) {
retval = verify_irix_interpreter(&interp_elf_ex);
if(retval)
- goto out_interp;
+ goto out_free_interp;
}
-
+
/* OK, we are done with that, now set up the arg stuff,
* and then start this sucker up.
*/
retval = -E2BIG;
if (!bprm->sh_bang && !bprm->p)
- goto out_interp;
-
+ goto out_free_interp;
+
/* Flush all traces of the currently running executable */
retval = flush_old_exec(bprm);
if (retval)
- goto out_interp;
+ goto out_free_dentry;
/* OK, This is the point of no return */
current->mm->end_data = 0;
@@ -716,15 +716,16 @@
current->mm->rss = 0;
setup_arg_pages(bprm);
current->mm->start_stack = bprm->p;
-
+
/* At this point, we assume that the image should be loaded at
* fixed address, not at a variable address.
*/
old_fs = get_fs();
set_fs(get_ds());
-
- map_executable(file, elf_phdata, elf_ex.e_phnum, &elf_stack, &load_addr,
- &start_code, &elf_bss, &end_code, &end_data, &elf_brk);
+
+ map_executable(file, elf_phdata, elf_ex.e_phnum, &elf_stack,
+ &load_addr, &start_code, &elf_bss, &end_code,
+ &end_data, &elf_brk);
if(elf_interpreter) {
retval = map_interpreter(elf_phdata, &interp_elf_ex,
@@ -736,12 +737,12 @@
printk("Unable to load IRIX ELF interpreter\n");
send_sig(SIGSEGV, current, 0);
retval = 0;
- goto out_file;
+ goto out_free_file;
}
}
set_fs(old_fs);
-
+
kfree(elf_phdata);
fput(file);
sys_close(elf_exec_fileno);
@@ -806,17 +807,20 @@
if (current->flags & PF_PTRACED)
send_sig(SIGTRAP, current, 0);
return 0;
+out:
+ return retval;
-out_interp:
- if(elf_interpreter) {
- kfree(elf_interpreter);
- }
-out_file:
+out_free_dentry:
+ dput(interpreter_dentry);
+out_free_interp:
+ if (elf_interpreter)
+ kfree(elf_interpreter);
+out_free_file:
fput(file);
sys_close(elf_exec_fileno);
-out_phdata:
+out_free_ph:
kfree (elf_phdata);
- return retval;
+ goto out;
}
static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
@@ -866,15 +870,14 @@
if (error != sizeof(elf_ex))
return -ENOEXEC;
- if (elf_ex.e_ident[0] != 0x7f ||
- strncmp(&elf_ex.e_ident[1], "ELF",3) != 0)
+ if (memcmp(elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
return -ENOEXEC;
/* First of all, some simple consistency checks. */
if(elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
!elf_check_arch(elf_ex.e_machine) ||
- (!dentry->d_inode->i_op ||
- !dentry->d_inode->i_op->default_file_ops->mmap))
+ (!dentry->d_inode->i_fop ||
+ !dentry->d_inode->i_fop->mmap))
return -ENOEXEC;
/* Now read in all of the header information. */
@@ -982,7 +985,7 @@
return -EACCES;
if(!filp->f_op) {
printk("irix_mapelf: Bogon filp!\n");
- fput(file);
+ fput(filp);
return -EACCES;
}
@@ -1000,7 +1003,7 @@
if(retval != (hp->p_vaddr & 0xfffff000)) {
printk("irix_mapelf: do_mmap fails with %d!\n", retval);
- fput(file);
+ fput(filp);
return retval;
}
}
@@ -1008,7 +1011,7 @@
#ifdef DEBUG_ELF
printk("irix_mapelf: Success, returning %08lx\n", user_phdrp->p_vaddr);
#endif
- fput(file);
+ fput(filp);
return user_phdrp->p_vaddr;
}
@@ -1070,20 +1073,22 @@
static int notesize(struct memelfnote *en)
{
int sz;
-
+
sz = sizeof(struct elf_note);
sz += roundup(strlen(en->name), 4);
sz += roundup(en->datasz, 4);
-
+
return sz;
}
/* #define DEBUG */
#define DUMP_WRITE(addr, nr) \
- do { if (!dump_write(file, (addr), (nr))) return 0; } while(0)
+ if (!dump_write(file, (addr), (nr))) \
+ goto end_coredump;
#define DUMP_SEEK(off) \
- do { if (!dump_seek(file, (off))) return 0; } while(0)
+ if (!dump_seek(file, (off))) \
+ goto end_coredump;
static int writenote(struct memelfnote *men, struct file *file)
{
@@ -1101,6 +1106,9 @@
DUMP_SEEK(roundup((unsigned long)file->f_pos, 4)); /* XXX */
return 1;
+
+end_coredump:
+ return 0;
}
#undef DUMP_WRITE
#undef DUMP_SEEK
@@ -1111,6 +1119,7 @@
#define DUMP_SEEK(off) \
if (!dump_seek(file, (off))) \
goto end_coredump;
+
/* Actual dumper.
*
* This is a two-pass process; first we find the offsets of the bits,
@@ -1164,7 +1173,7 @@
elf.e_ident[EI_DATA] = ELFDATA2LSB;
elf.e_ident[EI_VERSION] = EV_CURRENT;
memset(elf.e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);
-
+
elf.e_type = ET_CORE;
elf.e_machine = ELF_ARCH;
elf.e_version = EV_CURRENT;
@@ -1255,7 +1264,7 @@
notes[2].type = NT_TASKSTRUCT;
notes[2].datasz = sizeof(*current);
notes[2].data = current;
-
+
/* Try to dump the FPU. */
prstatus.pr_fpvalid = dump_fpu (&fpu);
if (!prstatus.pr_fpvalid) {
@@ -1266,7 +1275,7 @@
notes[3].datasz = sizeof(fpu);
notes[3].data = &fpu;
}
-
+
/* Write notes phdr entry. */
{
struct elf_phdr phdr;
@@ -1345,34 +1354,24 @@
(off_t) file->f_pos, offset);
}
- end_coredump:
+end_coredump:
set_fs(fs);
-#ifndef CONFIG_BINFMT_ELF
+#ifndef CONFIG_BINFMT_IRIX
MOD_DEC_USE_COUNT;
#endif
return has_dumped;
}
-int __init init_irix_binfmt(void)
+static int __init init_irix_binfmt(void)
{
return register_binfmt(&irix_format);
}
-#ifdef MODULE
-
-int init_module(void)
-{
- /* Install the COFF, ELF and XOUT loaders.
- * N.B. We *rely* on the table being the right size with the
- * right number of free slots...
- */
- return init_irix_binfmt();
-}
-
-
-void cleanup_module( void)
+static void __exit cleanup_module(void)
{
/* Remove the IRIX ELF loaders. */
unregister_binfmt(&irix_format);
}
-#endif
+
+module_init(init_irix_binfmt)
+module_exit(exit_irix_binfmt)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)