aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven J. Hill <sjhill@realitydiluted.com>2005-02-19 11:15:54 -0500
committerRalf Baechle <ralf@linux-mips.org>2005-10-29 14:30:39 -0400
commit7ee8798f3756fc473e63abeba56fae3e192ce71f (patch)
tree0aa88cef08a4feb76b961615bf9673893f46d435
parentdd193261482ac235f08836750d22689fd55c5ca0 (diff)
Until I figure out why NFS filesystems are having problems with
the 'load_irix_binary' and having kernel faults, Irix support is disabled. I suspect locking of some sort, but I will now have to investigate further. Static IRIX binaries are now being detected properly and are using the ELF interpreter found in this file. Signed-off-by: Steven J. Hill <sjhill@realitydiluted.com> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/kernel/irixelf.c226
-rw-r--r--include/asm-mips/elf.h3
2 files changed, 123 insertions, 106 deletions
diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
index 4af20cd91f9f..881f125eecb4 100644
--- a/arch/mips/kernel/irixelf.c
+++ b/arch/mips/kernel/irixelf.c
@@ -8,7 +8,7 @@
8 * 8 *
9 * Copyright (C) 1993 - 1994 Eric Youngdale <ericy@cais.com> 9 * Copyright (C) 1993 - 1994 Eric Youngdale <ericy@cais.com>
10 * Copyright (C) 1996 - 2004 David S. Miller <dm@engr.sgi.com> 10 * Copyright (C) 1996 - 2004 David S. Miller <dm@engr.sgi.com>
11 * Copyright (C) 2004 Steven J. Hill <sjhill@realitydiluted.com> 11 * Copyright (C) 2004 - 2005 Steven J. Hill <sjhill@realitydiluted.com>
12 */ 12 */
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/fs.h> 14#include <linux/fs.h>
@@ -31,15 +31,16 @@
31#include <linux/elfcore.h> 31#include <linux/elfcore.h>
32#include <linux/smp_lock.h> 32#include <linux/smp_lock.h>
33 33
34#include <asm/uaccess.h>
35#include <asm/mipsregs.h> 34#include <asm/mipsregs.h>
35#include <asm/namei.h>
36#include <asm/prctl.h> 36#include <asm/prctl.h>
37#include <asm/uaccess.h>
37 38
38#define DLINFO_ITEMS 12 39#define DLINFO_ITEMS 12
39 40
40#include <linux/elf.h> 41#include <linux/elf.h>
41 42
42#undef DEBUG_ELF 43#undef DEBUG
43 44
44static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs); 45static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs);
45static int load_irix_library(struct file *); 46static int load_irix_library(struct file *);
@@ -55,7 +56,7 @@ static struct linux_binfmt irix_format = {
55#define elf_addr_t unsigned long 56#define elf_addr_t unsigned long
56#endif 57#endif
57 58
58#ifdef DEBUG_ELF 59#ifdef DEBUG
59/* Debugging routines. */ 60/* Debugging routines. */
60static char *get_elf_p_type(Elf32_Word p_type) 61static char *get_elf_p_type(Elf32_Word p_type)
61{ 62{
@@ -120,7 +121,7 @@ static void dump_phdrs(struct elf_phdr *ep, int pnum)
120 print_phdr(i, ep); 121 print_phdr(i, ep);
121 } 122 }
122} 123}
123#endif /* (DEBUG_ELF) */ 124#endif /* DEBUG */
124 125
125static void set_brk(unsigned long start, unsigned long end) 126static void set_brk(unsigned long start, unsigned long end)
126{ 127{
@@ -150,16 +151,16 @@ static void padzero(unsigned long elf_bss)
150 } 151 }
151} 152}
152 153
153unsigned long * create_irix_tables(char * p, int argc, int envc, 154static unsigned long * create_irix_tables(char * p, int argc, int envc,
154 struct elfhdr * exec, unsigned int load_addr, 155 struct elfhdr * exec, unsigned int load_addr,
155 unsigned int interp_load_addr, 156 unsigned int interp_load_addr, struct pt_regs *regs,
156 struct pt_regs *regs, struct elf_phdr *ephdr) 157 struct elf_phdr *ephdr)
157{ 158{
158 elf_addr_t *argv; 159 elf_addr_t *argv;
159 elf_addr_t *envp; 160 elf_addr_t *envp;
160 elf_addr_t *sp, *csp; 161 elf_addr_t *sp, *csp;
161 162
162#ifdef DEBUG_ELF 163#ifdef DEBUG
163 printk("create_irix_tables: p[%p] argc[%d] envc[%d] " 164 printk("create_irix_tables: p[%p] argc[%d] envc[%d] "
164 "load_addr[%08x] interp_load_addr[%08x]\n", 165 "load_addr[%08x] interp_load_addr[%08x]\n",
165 p, argc, envc, load_addr, interp_load_addr); 166 p, argc, envc, load_addr, interp_load_addr);
@@ -248,14 +249,13 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex,
248 last_bss = 0; 249 last_bss = 0;
249 error = load_addr = 0; 250 error = load_addr = 0;
250 251
251#ifdef DEBUG_ELF 252#ifdef DEBUG
252 print_elfhdr(interp_elf_ex); 253 print_elfhdr(interp_elf_ex);
253#endif 254#endif
254 255
255 /* First of all, some simple consistency checks */ 256 /* First of all, some simple consistency checks */
256 if ((interp_elf_ex->e_type != ET_EXEC && 257 if ((interp_elf_ex->e_type != ET_EXEC &&
257 interp_elf_ex->e_type != ET_DYN) || 258 interp_elf_ex->e_type != ET_DYN) ||
258 !irix_elf_check_arch(interp_elf_ex) ||
259 !interpreter->f_op->mmap) { 259 !interpreter->f_op->mmap) {
260 printk("IRIX interp has bad e_type %d\n", interp_elf_ex->e_type); 260 printk("IRIX interp has bad e_type %d\n", interp_elf_ex->e_type);
261 return 0xffffffff; 261 return 0xffffffff;
@@ -290,7 +290,7 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex,
290 (char *) elf_phdata, 290 (char *) elf_phdata,
291 sizeof(struct elf_phdr) * interp_elf_ex->e_phnum); 291 sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
292 292
293#ifdef DEBUG_ELF 293#ifdef DEBUG
294 dump_phdrs(elf_phdata, interp_elf_ex->e_phnum); 294 dump_phdrs(elf_phdata, interp_elf_ex->e_phnum);
295#endif 295#endif
296 296
@@ -306,13 +306,11 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex,
306 elf_type |= MAP_FIXED; 306 elf_type |= MAP_FIXED;
307 vaddr = eppnt->p_vaddr; 307 vaddr = eppnt->p_vaddr;
308 308
309#ifdef DEBUG_ELF 309 pr_debug("INTERP do_mmap(%p, %08lx, %08lx, %08lx, %08lx, %08lx) ",
310 printk("INTERP do_mmap(%p, %08lx, %08lx, %08lx, %08lx, %08lx) ",
311 interpreter, vaddr, 310 interpreter, vaddr,
312 (unsigned long) (eppnt->p_filesz + (eppnt->p_vaddr & 0xfff)), 311 (unsigned long) (eppnt->p_filesz + (eppnt->p_vaddr & 0xfff)),
313 (unsigned long) elf_prot, (unsigned long) elf_type, 312 (unsigned long) elf_prot, (unsigned long) elf_type,
314 (unsigned long) (eppnt->p_offset & 0xfffff000)); 313 (unsigned long) (eppnt->p_offset & 0xfffff000));
315#endif
316 down_write(&current->mm->mmap_sem); 314 down_write(&current->mm->mmap_sem);
317 error = do_mmap(interpreter, vaddr, 315 error = do_mmap(interpreter, vaddr,
318 eppnt->p_filesz + (eppnt->p_vaddr & 0xfff), 316 eppnt->p_filesz + (eppnt->p_vaddr & 0xfff),
@@ -324,14 +322,10 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex,
324 printk("Aieee IRIX interp mmap error=%d\n", error); 322 printk("Aieee IRIX interp mmap error=%d\n", error);
325 break; /* Real error */ 323 break; /* Real error */
326 } 324 }
327#ifdef DEBUG_ELF 325 pr_debug("error=%08lx ", (unsigned long) error);
328 printk("error=%08lx ", (unsigned long) error);
329#endif
330 if(!load_addr && interp_elf_ex->e_type == ET_DYN) { 326 if(!load_addr && interp_elf_ex->e_type == ET_DYN) {
331 load_addr = error; 327 load_addr = error;
332#ifdef DEBUG_ELF 328 pr_debug("load_addr = error ");
333 printk("load_addr = error ");
334#endif
335 } 329 }
336 330
337 /* Find the end of the file mapping for this phdr, and keep 331 /* Find the end of the file mapping for this phdr, and keep
@@ -345,17 +339,13 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex,
345 */ 339 */
346 k = eppnt->p_memsz + eppnt->p_vaddr; 340 k = eppnt->p_memsz + eppnt->p_vaddr;
347 if(k > last_bss) last_bss = k; 341 if(k > last_bss) last_bss = k;
348#ifdef DEBUG_ELF 342 pr_debug("\n");
349 printk("\n");
350#endif
351 } 343 }
352 } 344 }
353 345
354 /* Now use mmap to map the library into memory. */ 346 /* Now use mmap to map the library into memory. */
355 if(error < 0 && error > -1024) { 347 if(error < 0 && error > -1024) {
356#ifdef DEBUG_ELF 348 pr_debug("got error %d\n", error);
357 printk("got error %d\n", error);
358#endif
359 kfree(elf_phdata); 349 kfree(elf_phdata);
360 return 0xffffffff; 350 return 0xffffffff;
361 } 351 }
@@ -365,16 +355,12 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex,
365 * that there are zero-mapped pages up to and including the 355 * that there are zero-mapped pages up to and including the
366 * last bss page. 356 * last bss page.
367 */ 357 */
368#ifdef DEBUG_ELF 358 pr_debug("padzero(%08lx) ", (unsigned long) (elf_bss));
369 printk("padzero(%08lx) ", (unsigned long) (elf_bss));
370#endif
371 padzero(elf_bss); 359 padzero(elf_bss);
372 len = (elf_bss + 0xfff) & 0xfffff000; /* What we have mapped so far */ 360 len = (elf_bss + 0xfff) & 0xfffff000; /* What we have mapped so far */
373 361
374#ifdef DEBUG_ELF 362 pr_debug("last_bss[%08lx] len[%08lx]\n", (unsigned long) last_bss,
375 printk("last_bss[%08lx] len[%08lx]\n", (unsigned long) last_bss, 363 (unsigned long) len);
376 (unsigned long) len);
377#endif
378 364
379 /* Map the last of the bss segment */ 365 /* Map the last of the bss segment */
380 if (last_bss > len) { 366 if (last_bss > len) {
@@ -396,12 +382,7 @@ static int verify_binary(struct elfhdr *ehp, struct linux_binprm *bprm)
396 382
397 /* First of all, some simple consistency checks */ 383 /* First of all, some simple consistency checks */
398 if((ehp->e_type != ET_EXEC && ehp->e_type != ET_DYN) || 384 if((ehp->e_type != ET_EXEC && ehp->e_type != ET_DYN) ||
399 !irix_elf_check_arch(ehp) || !bprm->file->f_op->mmap) { 385 !bprm->file->f_op->mmap) {
400 return -ENOEXEC;
401 }
402
403 /* Only support MIPS ARCH2 or greater IRIX binaries for now. */
404 if(!(ehp->e_flags & EF_MIPS_ARCH) && !(ehp->e_flags & 0x04)) {
405 return -ENOEXEC; 386 return -ENOEXEC;
406 } 387 }
407 388
@@ -411,16 +392,17 @@ static int verify_binary(struct elfhdr *ehp, struct linux_binprm *bprm)
411 * XXX all registers as 64bits on cpu's capable of this at 392 * XXX all registers as 64bits on cpu's capable of this at
412 * XXX exception time plus frob the XTLB exception vector. 393 * XXX exception time plus frob the XTLB exception vector.
413 */ 394 */
414 if((ehp->e_flags & 0x20)) { 395 if((ehp->e_flags & EF_MIPS_ABI2))
415 return -ENOEXEC; 396 return -ENOEXEC;
416 }
417 397
418 return 0; /* It's ok. */ 398 return 0;
419} 399}
420 400
421#define IRIX_INTERP_PREFIX "/usr/gnemul/irix" 401/*
422 402 * This is where the detailed check is performed. Irix binaries
423/* Look for an IRIX ELF interpreter. */ 403 * use interpreters with 'libc.so' in the name, so this function
404 * can differentiate between Linux and Irix binaries.
405 */
424static inline int look_for_irix_interpreter(char **name, 406static inline int look_for_irix_interpreter(char **name,
425 struct file **interpreter, 407 struct file **interpreter,
426 struct elfhdr *interp_elf_ex, 408 struct elfhdr *interp_elf_ex,
@@ -440,12 +422,13 @@ static inline int look_for_irix_interpreter(char **name,
440 if (*name != NULL) 422 if (*name != NULL)
441 goto out; 423 goto out;
442 424
443 *name = kmalloc((epp->p_filesz + strlen(IRIX_INTERP_PREFIX)), 425 *name = (char *) kmalloc((epp->p_filesz +
444 GFP_KERNEL); 426 strlen(IRIX_EMUL)),
427 GFP_KERNEL);
445 if (!*name) 428 if (!*name)
446 return -ENOMEM; 429 return -ENOMEM;
447 430
448 strcpy(*name, IRIX_INTERP_PREFIX); 431 strcpy(*name, IRIX_EMUL);
449 retval = kernel_read(bprm->file, epp->p_offset, (*name + 16), 432 retval = kernel_read(bprm->file, epp->p_offset, (*name + 16),
450 epp->p_filesz); 433 epp->p_filesz);
451 if (retval < 0) 434 if (retval < 0)
@@ -562,7 +545,7 @@ static inline int map_interpreter(struct elf_phdr *epp, struct elfhdr *ihp,
562 * process and the system, here we map the page and fill the 545 * process and the system, here we map the page and fill the
563 * structure 546 * structure
564 */ 547 */
565void irix_map_prda_page (void) 548static void irix_map_prda_page(void)
566{ 549{
567 unsigned long v; 550 unsigned long v;
568 struct prda *pp; 551 struct prda *pp;
@@ -601,14 +584,33 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
601 584
602 load_addr = 0; 585 load_addr = 0;
603 has_interp = has_ephdr = 0; 586 has_interp = has_ephdr = 0;
604 elf_ihdr = elf_ephdr = 0; 587 elf_ihdr = elf_ephdr = NULL;
605 elf_ex = *((struct elfhdr *) bprm->buf); 588 elf_ex = *((struct elfhdr *) bprm->buf);
606 retval = -ENOEXEC; 589 retval = -ENOEXEC;
607 590
608 if (verify_binary(&elf_ex, bprm)) 591 if (verify_binary(&elf_ex, bprm))
609 goto out; 592 goto out;
610 593
611#ifdef DEBUG_ELF 594 /*
595 * Telling -o32 static binaries from Linux and Irix apart from each
596 * other is difficult. There are 2 differences to be noted for static
597 * binaries from the 2 operating systems:
598 *
599 * 1) Irix binaries have their .text section before their .init
600 * section. Linux binaries are just the opposite.
601 *
602 * 2) Irix binaries usually have <= 12 sections and Linux
603 * binaries have > 20.
604 *
605 * We will use Method #2 since Method #1 would require us to read in
606 * the section headers which is way too much overhead. This appears
607 * to work for everything we have ran into so far. If anyone has a
608 * better method to tell the binaries apart, I'm listening.
609 */
610 if (elf_ex.e_shnum > 20)
611 goto out;
612
613#ifdef DEBUG
612 print_elfhdr(&elf_ex); 614 print_elfhdr(&elf_ex);
613#endif 615#endif
614 616
@@ -623,11 +625,10 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
623 } 625 }
624 626
625 retval = kernel_read(bprm->file, elf_ex.e_phoff, (char *)elf_phdata, size); 627 retval = kernel_read(bprm->file, elf_ex.e_phoff, (char *)elf_phdata, size);
626
627 if (retval < 0) 628 if (retval < 0)
628 goto out_free_ph; 629 goto out_free_ph;
629 630
630#ifdef DEBUG_ELF 631#ifdef DEBUG
631 dump_phdrs(elf_phdata, elf_ex.e_phnum); 632 dump_phdrs(elf_phdata, elf_ex.e_phnum);
632#endif 633#endif
633 634
@@ -644,9 +645,8 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
644 break; 645 break;
645 }; 646 };
646 } 647 }
647#ifdef DEBUG_ELF 648
648 printk("\n"); 649 pr_debug("\n");
649#endif
650 650
651 elf_bss = 0; 651 elf_bss = 0;
652 elf_brk = 0; 652 elf_brk = 0;
@@ -657,12 +657,19 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
657 end_code = 0; 657 end_code = 0;
658 end_data = 0; 658 end_data = 0;
659 659
660 retval = look_for_irix_interpreter(&elf_interpreter, 660 /*
661 &interpreter, 661 * If we get a return value, we change the value to be ENOEXEC
662 * so that we can exit gracefully and the main binary format
663 * search loop in 'fs/exec.c' will move onto the next handler
664 * which should be the normal ELF binary handler.
665 */
666 retval = look_for_irix_interpreter(&elf_interpreter, &interpreter,
662 &interp_elf_ex, elf_phdata, bprm, 667 &interp_elf_ex, elf_phdata, bprm,
663 elf_ex.e_phnum); 668 elf_ex.e_phnum);
664 if (retval) 669 if (retval) {
670 retval = -ENOEXEC;
665 goto out_free_file; 671 goto out_free_file;
672 }
666 673
667 if (elf_interpreter) { 674 if (elf_interpreter) {
668 retval = verify_irix_interpreter(&interp_elf_ex); 675 retval = verify_irix_interpreter(&interp_elf_ex);
@@ -746,18 +753,16 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
746 * IRIX maps a page at 0x200000 which holds some system 753 * IRIX maps a page at 0x200000 which holds some system
747 * information. Programs depend on this. 754 * information. Programs depend on this.
748 */ 755 */
749 irix_map_prda_page (); 756 irix_map_prda_page();
750 757
751 padzero(elf_bss); 758 padzero(elf_bss);
752 759
753#ifdef DEBUG_ELF 760 pr_debug("(start_brk) %lx\n" , (long) current->mm->start_brk);
754 printk("(start_brk) %lx\n" , (long) current->mm->start_brk); 761 pr_debug("(end_code) %lx\n" , (long) current->mm->end_code);
755 printk("(end_code) %lx\n" , (long) current->mm->end_code); 762 pr_debug("(start_code) %lx\n" , (long) current->mm->start_code);
756 printk("(start_code) %lx\n" , (long) current->mm->start_code); 763 pr_debug("(end_data) %lx\n" , (long) current->mm->end_data);
757 printk("(end_data) %lx\n" , (long) current->mm->end_data); 764 pr_debug("(start_stack) %lx\n" , (long) current->mm->start_stack);
758 printk("(start_stack) %lx\n" , (long) current->mm->start_stack); 765 pr_debug("(brk) %lx\n" , (long) current->mm->brk);
759 printk("(brk) %lx\n" , (long) current->mm->brk);
760#endif
761 766
762#if 0 /* XXX No fucking way dude... */ 767#if 0 /* XXX No fucking way dude... */
763 /* Why this, you ask??? Well SVr4 maps page 0 as read-only, 768 /* Why this, you ask??? Well SVr4 maps page 0 as read-only,
@@ -782,8 +787,7 @@ out_free_dentry:
782 allow_write_access(interpreter); 787 allow_write_access(interpreter);
783 fput(interpreter); 788 fput(interpreter);
784out_free_interp: 789out_free_interp:
785 if (elf_interpreter) 790 kfree(elf_interpreter);
786 kfree(elf_interpreter);
787out_free_file: 791out_free_file:
788out_free_ph: 792out_free_ph:
789 kfree (elf_phdata); 793 kfree (elf_phdata);
@@ -813,7 +817,7 @@ static int load_irix_library(struct file *file)
813 817
814 /* First of all, some simple consistency checks. */ 818 /* First of all, some simple consistency checks. */
815 if(elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 || 819 if(elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
816 !irix_elf_check_arch(&elf_ex) || !file->f_op->mmap) 820 !file->f_op->mmap)
817 return -ENOEXEC; 821 return -ENOEXEC;
818 822
819 /* Now read in all of the header information. */ 823 /* Now read in all of the header information. */
@@ -876,33 +880,34 @@ static int load_irix_library(struct file *file)
876 */ 880 */
877unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt) 881unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt)
878{ 882{
883 unsigned long type, vaddr, filesz, offset, flags;
879 struct elf_phdr *hp; 884 struct elf_phdr *hp;
880 struct file *filp; 885 struct file *filp;
881 int i, retval; 886 int i, retval;
882 887
883#ifdef DEBUG_ELF 888 pr_debug("irix_mapelf: fd[%d] user_phdrp[%p] cnt[%d]\n",
884 printk("irix_mapelf: fd[%d] user_phdrp[%p] cnt[%d]\n", 889 fd, user_phdrp, cnt);
885 fd, user_phdrp, cnt);
886#endif
887 890
888 /* First get the verification out of the way. */ 891 /* First get the verification out of the way. */
889 hp = user_phdrp; 892 hp = user_phdrp;
890 if (!access_ok(VERIFY_READ, hp, (sizeof(struct elf_phdr) * cnt))) { 893 if (!access_ok(VERIFY_READ, hp, (sizeof(struct elf_phdr) * cnt))) {
891#ifdef DEBUG_ELF 894 pr_debug("irix_mapelf: bad pointer to ELF PHDR!\n");
892 printk("irix_mapelf: access_ok fails!\n"); 895
893#endif
894 return -EFAULT; 896 return -EFAULT;
895 } 897 }
896 898
897#ifdef DEBUG_ELF 899#ifdef DEBUG
898 dump_phdrs(user_phdrp, cnt); 900 dump_phdrs(user_phdrp, cnt);
899#endif 901#endif
900 902
901 for(i = 0; i < cnt; i++, hp++) 903 for (i = 0; i < cnt; i++, hp++) {
902 if(hp->p_type != PT_LOAD) { 904 if (__get_user(type, &hp->p_type))
905 return -EFAULT;
906 if (type != PT_LOAD) {
903 printk("irix_mapelf: One section is not PT_LOAD!\n"); 907 printk("irix_mapelf: One section is not PT_LOAD!\n");
904 return -ENOEXEC; 908 return -ENOEXEC;
905 } 909 }
910 }
906 911
907 filp = fget(fd); 912 filp = fget(fd);
908 if (!filp) 913 if (!filp)
@@ -917,29 +922,40 @@ unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt)
917 for(i = 0; i < cnt; i++, hp++) { 922 for(i = 0; i < cnt; i++, hp++) {
918 int prot; 923 int prot;
919 924
920 prot = (hp->p_flags & PF_R) ? PROT_READ : 0; 925 retval = __get_user(vaddr, &hp->p_vaddr);
921 prot |= (hp->p_flags & PF_W) ? PROT_WRITE : 0; 926 retval |= __get_user(filesz, &hp->p_filesz);
922 prot |= (hp->p_flags & PF_X) ? PROT_EXEC : 0; 927 retval |= __get_user(offset, &hp->p_offset);
928 retval |= __get_user(flags, &hp->p_flags);
929 if (retval)
930 return retval;
931
932 prot = (flags & PF_R) ? PROT_READ : 0;
933 prot |= (flags & PF_W) ? PROT_WRITE : 0;
934 prot |= (flags & PF_X) ? PROT_EXEC : 0;
935
923 down_write(&current->mm->mmap_sem); 936 down_write(&current->mm->mmap_sem);
924 retval = do_mmap(filp, (hp->p_vaddr & 0xfffff000), 937 retval = do_mmap(filp, (vaddr & 0xfffff000),
925 (hp->p_filesz + (hp->p_vaddr & 0xfff)), 938 (filesz + (vaddr & 0xfff)),
926 prot, (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE), 939 prot, (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
927 (hp->p_offset & 0xfffff000)); 940 (offset & 0xfffff000));
928 up_write(&current->mm->mmap_sem); 941 up_write(&current->mm->mmap_sem);
929 942
930 if(retval != (hp->p_vaddr & 0xfffff000)) { 943 if (retval != (vaddr & 0xfffff000)) {
931 printk("irix_mapelf: do_mmap fails with %d!\n", retval); 944 printk("irix_mapelf: do_mmap fails with %d!\n", retval);
932 fput(filp); 945 fput(filp);
933 return retval; 946 return retval;
934 } 947 }
935 } 948 }
936 949
937#ifdef DEBUG_ELF 950 pr_debug("irix_mapelf: Success, returning %08lx\n",
938 printk("irix_mapelf: Success, returning %08lx\n", 951 (unsigned long) user_phdrp->p_vaddr);
939 (unsigned long) user_phdrp->p_vaddr); 952
940#endif
941 fput(filp); 953 fput(filp);
942 return user_phdrp->p_vaddr; 954
955 if (__get_user(vaddr, &user_phdrp->p_vaddr))
956 return -EFAULT;
957
958 return vaddr;
943} 959}
944 960
945/* 961/*
@@ -954,7 +970,7 @@ unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt)
954 */ 970 */
955static int dump_write(struct file *file, const void *addr, int nr) 971static int dump_write(struct file *file, const void *addr, int nr)
956{ 972{
957 return file->f_op->write(file, addr, nr, &file->f_pos) == nr; 973 return file->f_op->write(file, (const char *) addr, nr, &file->f_pos) == nr;
958} 974}
959 975
960static int dump_seek(struct file *file, off_t off) 976static int dump_seek(struct file *file, off_t off)
@@ -1073,7 +1089,7 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
1073 /* Count what's needed to dump, up to the limit of coredump size. */ 1089 /* Count what's needed to dump, up to the limit of coredump size. */
1074 segs = 0; 1090 segs = 0;
1075 size = 0; 1091 size = 0;
1076 for(vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) { 1092 for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
1077 if (maydump(vma)) 1093 if (maydump(vma))
1078 { 1094 {
1079 int sz = vma->vm_end-vma->vm_start; 1095 int sz = vma->vm_end-vma->vm_start;
@@ -1187,9 +1203,9 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
1187 1203
1188 len = current->mm->arg_end - current->mm->arg_start; 1204 len = current->mm->arg_end - current->mm->arg_start;
1189 len = len >= ELF_PRARGSZ ? ELF_PRARGSZ : len; 1205 len = len >= ELF_PRARGSZ ? ELF_PRARGSZ : len;
1190 copy_from_user(&psinfo.pr_psargs, 1206 (void *) copy_from_user(&psinfo.pr_psargs,
1191 (const char *)current->mm->arg_start, len); 1207 (const char *)current->mm->arg_start, len);
1192 for(i = 0; i < len; i++) 1208 for (i = 0; i < len; i++)
1193 if (psinfo.pr_psargs[i] == 0) 1209 if (psinfo.pr_psargs[i] == 0)
1194 psinfo.pr_psargs[i] = ' '; 1210 psinfo.pr_psargs[i] = ' ';
1195 psinfo.pr_psargs[len] = 0; 1211 psinfo.pr_psargs[len] = 0;
@@ -1256,8 +1272,10 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
1256 phdr.p_memsz = sz; 1272 phdr.p_memsz = sz;
1257 offset += phdr.p_filesz; 1273 offset += phdr.p_filesz;
1258 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0; 1274 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
1259 if (vma->vm_flags & VM_WRITE) phdr.p_flags |= PF_W; 1275 if (vma->vm_flags & VM_WRITE)
1260 if (vma->vm_flags & VM_EXEC) phdr.p_flags |= PF_X; 1276 phdr.p_flags |= PF_W;
1277 if (vma->vm_flags & VM_EXEC)
1278 phdr.p_flags |= PF_X;
1261 phdr.p_align = PAGE_SIZE; 1279 phdr.p_align = PAGE_SIZE;
1262 1280
1263 DUMP_WRITE(&phdr, sizeof(phdr)); 1281 DUMP_WRITE(&phdr, sizeof(phdr));
@@ -1299,7 +1317,7 @@ end_coredump:
1299 1317
1300static int __init init_irix_binfmt(void) 1318static int __init init_irix_binfmt(void)
1301{ 1319{
1302 int init_inventory(void); 1320 extern int init_inventory(void);
1303 extern asmlinkage unsigned long sys_call_table; 1321 extern asmlinkage unsigned long sys_call_table;
1304 extern asmlinkage unsigned long sys_call_table_irix5; 1322 extern asmlinkage unsigned long sys_call_table_irix5;
1305 1323
@@ -1318,7 +1336,9 @@ static int __init init_irix_binfmt(void)
1318 1336
1319static void __exit exit_irix_binfmt(void) 1337static void __exit exit_irix_binfmt(void)
1320{ 1338{
1321 /* Remove the IRIX ELF loaders. */ 1339 /*
1340 * Remove the Irix ELF loader.
1341 */
1322 unregister_binfmt(&irix_format); 1342 unregister_binfmt(&irix_format);
1323} 1343}
1324 1344
diff --git a/include/asm-mips/elf.h b/include/asm-mips/elf.h
index e48811440015..a743da55e110 100644
--- a/include/asm-mips/elf.h
+++ b/include/asm-mips/elf.h
@@ -234,9 +234,6 @@ extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *);
234 234
235#endif /* __KERNEL__ */ 235#endif /* __KERNEL__ */
236 236
237/* This one accepts IRIX binaries. */
238#define irix_elf_check_arch(hdr) ((hdr)->e_flags & RHF_SGI_ONLY)
239
240#define USE_ELF_CORE_DUMP 237#define USE_ELF_CORE_DUMP
241#define ELF_EXEC_PAGESIZE PAGE_SIZE 238#define ELF_EXEC_PAGESIZE PAGE_SIZE
242 239