aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/irixelf.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/irixelf.c')
-rw-r--r--arch/mips/kernel/irixelf.c254
1 files changed, 133 insertions, 121 deletions
diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
index 4af20cd91f9f..10d3644e3608 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{
@@ -146,20 +147,20 @@ static void padzero(unsigned long elf_bss)
146 nbyte = elf_bss & (PAGE_SIZE-1); 147 nbyte = elf_bss & (PAGE_SIZE-1);
147 if (nbyte) { 148 if (nbyte) {
148 nbyte = PAGE_SIZE - nbyte; 149 nbyte = PAGE_SIZE - nbyte;
149 clear_user((void *) elf_bss, nbyte); 150 clear_user((void __user *) elf_bss, nbyte);
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,11 @@ 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 = kmalloc(epp->p_filesz + strlen(IRIX_EMUL), GFP_KERNEL);
444 GFP_KERNEL);
445 if (!*name) 426 if (!*name)
446 return -ENOMEM; 427 return -ENOMEM;
447 428
448 strcpy(*name, IRIX_INTERP_PREFIX); 429 strcpy(*name, IRIX_EMUL);
449 retval = kernel_read(bprm->file, epp->p_offset, (*name + 16), 430 retval = kernel_read(bprm->file, epp->p_offset, (*name + 16),
450 epp->p_filesz); 431 epp->p_filesz);
451 if (retval < 0) 432 if (retval < 0)
@@ -562,7 +543,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 543 * process and the system, here we map the page and fill the
563 * structure 544 * structure
564 */ 545 */
565void irix_map_prda_page (void) 546static void irix_map_prda_page(void)
566{ 547{
567 unsigned long v; 548 unsigned long v;
568 struct prda *pp; 549 struct prda *pp;
@@ -601,14 +582,33 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
601 582
602 load_addr = 0; 583 load_addr = 0;
603 has_interp = has_ephdr = 0; 584 has_interp = has_ephdr = 0;
604 elf_ihdr = elf_ephdr = 0; 585 elf_ihdr = elf_ephdr = NULL;
605 elf_ex = *((struct elfhdr *) bprm->buf); 586 elf_ex = *((struct elfhdr *) bprm->buf);
606 retval = -ENOEXEC; 587 retval = -ENOEXEC;
607 588
608 if (verify_binary(&elf_ex, bprm)) 589 if (verify_binary(&elf_ex, bprm))
609 goto out; 590 goto out;
610 591
611#ifdef DEBUG_ELF 592 /*
593 * Telling -o32 static binaries from Linux and Irix apart from each
594 * other is difficult. There are 2 differences to be noted for static
595 * binaries from the 2 operating systems:
596 *
597 * 1) Irix binaries have their .text section before their .init
598 * section. Linux binaries are just the opposite.
599 *
600 * 2) Irix binaries usually have <= 12 sections and Linux
601 * binaries have > 20.
602 *
603 * We will use Method #2 since Method #1 would require us to read in
604 * the section headers which is way too much overhead. This appears
605 * to work for everything we have ran into so far. If anyone has a
606 * better method to tell the binaries apart, I'm listening.
607 */
608 if (elf_ex.e_shnum > 20)
609 goto out;
610
611#ifdef DEBUG
612 print_elfhdr(&elf_ex); 612 print_elfhdr(&elf_ex);
613#endif 613#endif
614 614
@@ -623,11 +623,10 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
623 } 623 }
624 624
625 retval = kernel_read(bprm->file, elf_ex.e_phoff, (char *)elf_phdata, size); 625 retval = kernel_read(bprm->file, elf_ex.e_phoff, (char *)elf_phdata, size);
626
627 if (retval < 0) 626 if (retval < 0)
628 goto out_free_ph; 627 goto out_free_ph;
629 628
630#ifdef DEBUG_ELF 629#ifdef DEBUG
631 dump_phdrs(elf_phdata, elf_ex.e_phnum); 630 dump_phdrs(elf_phdata, elf_ex.e_phnum);
632#endif 631#endif
633 632
@@ -644,9 +643,8 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
644 break; 643 break;
645 }; 644 };
646 } 645 }
647#ifdef DEBUG_ELF 646
648 printk("\n"); 647 pr_debug("\n");
649#endif
650 648
651 elf_bss = 0; 649 elf_bss = 0;
652 elf_brk = 0; 650 elf_brk = 0;
@@ -657,12 +655,19 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
657 end_code = 0; 655 end_code = 0;
658 end_data = 0; 656 end_data = 0;
659 657
660 retval = look_for_irix_interpreter(&elf_interpreter, 658 /*
661 &interpreter, 659 * If we get a return value, we change the value to be ENOEXEC
660 * so that we can exit gracefully and the main binary format
661 * search loop in 'fs/exec.c' will move onto the next handler
662 * which should be the normal ELF binary handler.
663 */
664 retval = look_for_irix_interpreter(&elf_interpreter, &interpreter,
662 &interp_elf_ex, elf_phdata, bprm, 665 &interp_elf_ex, elf_phdata, bprm,
663 elf_ex.e_phnum); 666 elf_ex.e_phnum);
664 if (retval) 667 if (retval) {
668 retval = -ENOEXEC;
665 goto out_free_file; 669 goto out_free_file;
670 }
666 671
667 if (elf_interpreter) { 672 if (elf_interpreter) {
668 retval = verify_irix_interpreter(&interp_elf_ex); 673 retval = verify_irix_interpreter(&interp_elf_ex);
@@ -692,7 +697,6 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
692 /* Do this so that we can load the interpreter, if need be. We will 697 /* Do this so that we can load the interpreter, if need be. We will
693 * change some of these later. 698 * change some of these later.
694 */ 699 */
695 set_mm_counter(current->mm, rss, 0);
696 setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT); 700 setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT);
697 current->mm->start_stack = bprm->p; 701 current->mm->start_stack = bprm->p;
698 702
@@ -746,18 +750,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 750 * IRIX maps a page at 0x200000 which holds some system
747 * information. Programs depend on this. 751 * information. Programs depend on this.
748 */ 752 */
749 irix_map_prda_page (); 753 irix_map_prda_page();
750 754
751 padzero(elf_bss); 755 padzero(elf_bss);
752 756
753#ifdef DEBUG_ELF 757 pr_debug("(start_brk) %lx\n" , (long) current->mm->start_brk);
754 printk("(start_brk) %lx\n" , (long) current->mm->start_brk); 758 pr_debug("(end_code) %lx\n" , (long) current->mm->end_code);
755 printk("(end_code) %lx\n" , (long) current->mm->end_code); 759 pr_debug("(start_code) %lx\n" , (long) current->mm->start_code);
756 printk("(start_code) %lx\n" , (long) current->mm->start_code); 760 pr_debug("(end_data) %lx\n" , (long) current->mm->end_data);
757 printk("(end_data) %lx\n" , (long) current->mm->end_data); 761 pr_debug("(start_stack) %lx\n" , (long) current->mm->start_stack);
758 printk("(start_stack) %lx\n" , (long) current->mm->start_stack); 762 pr_debug("(brk) %lx\n" , (long) current->mm->brk);
759 printk("(brk) %lx\n" , (long) current->mm->brk);
760#endif
761 763
762#if 0 /* XXX No fucking way dude... */ 764#if 0 /* XXX No fucking way dude... */
763 /* Why this, you ask??? Well SVr4 maps page 0 as read-only, 765 /* Why this, you ask??? Well SVr4 maps page 0 as read-only,
@@ -782,8 +784,7 @@ out_free_dentry:
782 allow_write_access(interpreter); 784 allow_write_access(interpreter);
783 fput(interpreter); 785 fput(interpreter);
784out_free_interp: 786out_free_interp:
785 if (elf_interpreter) 787 kfree(elf_interpreter);
786 kfree(elf_interpreter);
787out_free_file: 788out_free_file:
788out_free_ph: 789out_free_ph:
789 kfree (elf_phdata); 790 kfree (elf_phdata);
@@ -813,7 +814,7 @@ static int load_irix_library(struct file *file)
813 814
814 /* First of all, some simple consistency checks. */ 815 /* First of all, some simple consistency checks. */
815 if(elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 || 816 if(elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
816 !irix_elf_check_arch(&elf_ex) || !file->f_op->mmap) 817 !file->f_op->mmap)
817 return -ENOEXEC; 818 return -ENOEXEC;
818 819
819 /* Now read in all of the header information. */ 820 /* Now read in all of the header information. */
@@ -874,35 +875,36 @@ static int load_irix_library(struct file *file)
874 * phdrs there are in the USER_PHDRP array. We return the vaddr the 875 * phdrs there are in the USER_PHDRP array. We return the vaddr the
875 * first phdr was successfully mapped to. 876 * first phdr was successfully mapped to.
876 */ 877 */
877unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt) 878unsigned long irix_mapelf(int fd, struct elf_phdr __user *user_phdrp, int cnt)
878{ 879{
879 struct elf_phdr *hp; 880 unsigned long type, vaddr, filesz, offset, flags;
881 struct elf_phdr __user *hp;
880 struct file *filp; 882 struct file *filp;
881 int i, retval; 883 int i, retval;
882 884
883#ifdef DEBUG_ELF 885 pr_debug("irix_mapelf: fd[%d] user_phdrp[%p] cnt[%d]\n",
884 printk("irix_mapelf: fd[%d] user_phdrp[%p] cnt[%d]\n", 886 fd, user_phdrp, cnt);
885 fd, user_phdrp, cnt);
886#endif
887 887
888 /* First get the verification out of the way. */ 888 /* First get the verification out of the way. */
889 hp = user_phdrp; 889 hp = user_phdrp;
890 if (!access_ok(VERIFY_READ, hp, (sizeof(struct elf_phdr) * cnt))) { 890 if (!access_ok(VERIFY_READ, hp, (sizeof(struct elf_phdr) * cnt))) {
891#ifdef DEBUG_ELF 891 pr_debug("irix_mapelf: bad pointer to ELF PHDR!\n");
892 printk("irix_mapelf: access_ok fails!\n"); 892
893#endif
894 return -EFAULT; 893 return -EFAULT;
895 } 894 }
896 895
897#ifdef DEBUG_ELF 896#ifdef DEBUG
898 dump_phdrs(user_phdrp, cnt); 897 dump_phdrs(user_phdrp, cnt);
899#endif 898#endif
900 899
901 for(i = 0; i < cnt; i++, hp++) 900 for (i = 0; i < cnt; i++, hp++) {
902 if(hp->p_type != PT_LOAD) { 901 if (__get_user(type, &hp->p_type))
902 return -EFAULT;
903 if (type != PT_LOAD) {
903 printk("irix_mapelf: One section is not PT_LOAD!\n"); 904 printk("irix_mapelf: One section is not PT_LOAD!\n");
904 return -ENOEXEC; 905 return -ENOEXEC;
905 } 906 }
907 }
906 908
907 filp = fget(fd); 909 filp = fget(fd);
908 if (!filp) 910 if (!filp)
@@ -917,29 +919,40 @@ unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt)
917 for(i = 0; i < cnt; i++, hp++) { 919 for(i = 0; i < cnt; i++, hp++) {
918 int prot; 920 int prot;
919 921
920 prot = (hp->p_flags & PF_R) ? PROT_READ : 0; 922 retval = __get_user(vaddr, &hp->p_vaddr);
921 prot |= (hp->p_flags & PF_W) ? PROT_WRITE : 0; 923 retval |= __get_user(filesz, &hp->p_filesz);
922 prot |= (hp->p_flags & PF_X) ? PROT_EXEC : 0; 924 retval |= __get_user(offset, &hp->p_offset);
925 retval |= __get_user(flags, &hp->p_flags);
926 if (retval)
927 return retval;
928
929 prot = (flags & PF_R) ? PROT_READ : 0;
930 prot |= (flags & PF_W) ? PROT_WRITE : 0;
931 prot |= (flags & PF_X) ? PROT_EXEC : 0;
932
923 down_write(&current->mm->mmap_sem); 933 down_write(&current->mm->mmap_sem);
924 retval = do_mmap(filp, (hp->p_vaddr & 0xfffff000), 934 retval = do_mmap(filp, (vaddr & 0xfffff000),
925 (hp->p_filesz + (hp->p_vaddr & 0xfff)), 935 (filesz + (vaddr & 0xfff)),
926 prot, (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE), 936 prot, (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
927 (hp->p_offset & 0xfffff000)); 937 (offset & 0xfffff000));
928 up_write(&current->mm->mmap_sem); 938 up_write(&current->mm->mmap_sem);
929 939
930 if(retval != (hp->p_vaddr & 0xfffff000)) { 940 if (retval != (vaddr & 0xfffff000)) {
931 printk("irix_mapelf: do_mmap fails with %d!\n", retval); 941 printk("irix_mapelf: do_mmap fails with %d!\n", retval);
932 fput(filp); 942 fput(filp);
933 return retval; 943 return retval;
934 } 944 }
935 } 945 }
936 946
937#ifdef DEBUG_ELF 947 pr_debug("irix_mapelf: Success, returning %08lx\n",
938 printk("irix_mapelf: Success, returning %08lx\n", 948 (unsigned long) user_phdrp->p_vaddr);
939 (unsigned long) user_phdrp->p_vaddr); 949
940#endif
941 fput(filp); 950 fput(filp);
942 return user_phdrp->p_vaddr; 951
952 if (__get_user(vaddr, &user_phdrp->p_vaddr))
953 return -EFAULT;
954
955 return vaddr;
943} 956}
944 957
945/* 958/*
@@ -952,9 +965,9 @@ unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt)
952/* These are the only things you should do on a core-file: use only these 965/* These are the only things you should do on a core-file: use only these
953 * functions to write out all the necessary info. 966 * functions to write out all the necessary info.
954 */ 967 */
955static int dump_write(struct file *file, const void *addr, int nr) 968static int dump_write(struct file *file, const void __user *addr, int nr)
956{ 969{
957 return file->f_op->write(file, addr, nr, &file->f_pos) == nr; 970 return file->f_op->write(file, (const char __user *) addr, nr, &file->f_pos) == nr;
958} 971}
959 972
960static int dump_seek(struct file *file, off_t off) 973static int dump_seek(struct file *file, off_t off)
@@ -1064,8 +1077,8 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
1064 struct elfhdr elf; 1077 struct elfhdr elf;
1065 off_t offset = 0, dataoff; 1078 off_t offset = 0, dataoff;
1066 int limit = current->signal->rlim[RLIMIT_CORE].rlim_cur; 1079 int limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
1067 int numnote = 4; 1080 int numnote = 3;
1068 struct memelfnote notes[4]; 1081 struct memelfnote notes[3];
1069 struct elf_prstatus prstatus; /* NT_PRSTATUS */ 1082 struct elf_prstatus prstatus; /* NT_PRSTATUS */
1070 elf_fpregset_t fpu; /* NT_PRFPREG */ 1083 elf_fpregset_t fpu; /* NT_PRFPREG */
1071 struct elf_prpsinfo psinfo; /* NT_PRPSINFO */ 1084 struct elf_prpsinfo psinfo; /* NT_PRPSINFO */
@@ -1073,7 +1086,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. */ 1086 /* Count what's needed to dump, up to the limit of coredump size. */
1074 segs = 0; 1087 segs = 0;
1075 size = 0; 1088 size = 0;
1076 for(vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) { 1089 for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
1077 if (maydump(vma)) 1090 if (maydump(vma))
1078 { 1091 {
1079 int sz = vma->vm_end-vma->vm_start; 1092 int sz = vma->vm_end-vma->vm_start;
@@ -1187,9 +1200,9 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
1187 1200
1188 len = current->mm->arg_end - current->mm->arg_start; 1201 len = current->mm->arg_end - current->mm->arg_start;
1189 len = len >= ELF_PRARGSZ ? ELF_PRARGSZ : len; 1202 len = len >= ELF_PRARGSZ ? ELF_PRARGSZ : len;
1190 copy_from_user(&psinfo.pr_psargs, 1203 (void *) copy_from_user(&psinfo.pr_psargs,
1191 (const char *)current->mm->arg_start, len); 1204 (const char __user *)current->mm->arg_start, len);
1192 for(i = 0; i < len; i++) 1205 for (i = 0; i < len; i++)
1193 if (psinfo.pr_psargs[i] == 0) 1206 if (psinfo.pr_psargs[i] == 0)
1194 psinfo.pr_psargs[i] = ' '; 1207 psinfo.pr_psargs[i] = ' ';
1195 psinfo.pr_psargs[len] = 0; 1208 psinfo.pr_psargs[len] = 0;
@@ -1198,20 +1211,15 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
1198 } 1211 }
1199 strlcpy(psinfo.pr_fname, current->comm, sizeof(psinfo.pr_fname)); 1212 strlcpy(psinfo.pr_fname, current->comm, sizeof(psinfo.pr_fname));
1200 1213
1201 notes[2].name = "CORE";
1202 notes[2].type = NT_TASKSTRUCT;
1203 notes[2].datasz = sizeof(*current);
1204 notes[2].data = current;
1205
1206 /* Try to dump the FPU. */ 1214 /* Try to dump the FPU. */
1207 prstatus.pr_fpvalid = dump_fpu (regs, &fpu); 1215 prstatus.pr_fpvalid = dump_fpu (regs, &fpu);
1208 if (!prstatus.pr_fpvalid) { 1216 if (!prstatus.pr_fpvalid) {
1209 numnote--; 1217 numnote--;
1210 } else { 1218 } else {
1211 notes[3].name = "CORE"; 1219 notes[2].name = "CORE";
1212 notes[3].type = NT_PRFPREG; 1220 notes[2].type = NT_PRFPREG;
1213 notes[3].datasz = sizeof(fpu); 1221 notes[2].datasz = sizeof(fpu);
1214 notes[3].data = &fpu; 1222 notes[2].data = &fpu;
1215 } 1223 }
1216 1224
1217 /* Write notes phdr entry. */ 1225 /* Write notes phdr entry. */
@@ -1256,8 +1264,10 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
1256 phdr.p_memsz = sz; 1264 phdr.p_memsz = sz;
1257 offset += phdr.p_filesz; 1265 offset += phdr.p_filesz;
1258 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0; 1266 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
1259 if (vma->vm_flags & VM_WRITE) phdr.p_flags |= PF_W; 1267 if (vma->vm_flags & VM_WRITE)
1260 if (vma->vm_flags & VM_EXEC) phdr.p_flags |= PF_X; 1268 phdr.p_flags |= PF_W;
1269 if (vma->vm_flags & VM_EXEC)
1270 phdr.p_flags |= PF_X;
1261 phdr.p_align = PAGE_SIZE; 1271 phdr.p_align = PAGE_SIZE;
1262 1272
1263 DUMP_WRITE(&phdr, sizeof(phdr)); 1273 DUMP_WRITE(&phdr, sizeof(phdr));
@@ -1283,7 +1293,7 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
1283#ifdef DEBUG 1293#ifdef DEBUG
1284 printk("elf_core_dump: writing %08lx %lx\n", addr, len); 1294 printk("elf_core_dump: writing %08lx %lx\n", addr, len);
1285#endif 1295#endif
1286 DUMP_WRITE((void *)addr, len); 1296 DUMP_WRITE((void __user *)addr, len);
1287 } 1297 }
1288 1298
1289 if ((off_t) file->f_pos != offset) { 1299 if ((off_t) file->f_pos != offset) {
@@ -1299,7 +1309,7 @@ end_coredump:
1299 1309
1300static int __init init_irix_binfmt(void) 1310static int __init init_irix_binfmt(void)
1301{ 1311{
1302 int init_inventory(void); 1312 extern int init_inventory(void);
1303 extern asmlinkage unsigned long sys_call_table; 1313 extern asmlinkage unsigned long sys_call_table;
1304 extern asmlinkage unsigned long sys_call_table_irix5; 1314 extern asmlinkage unsigned long sys_call_table_irix5;
1305 1315
@@ -1318,7 +1328,9 @@ static int __init init_irix_binfmt(void)
1318 1328
1319static void __exit exit_irix_binfmt(void) 1329static void __exit exit_irix_binfmt(void)
1320{ 1330{
1321 /* Remove the IRIX ELF loaders. */ 1331 /*
1332 * Remove the Irix ELF loader.
1333 */
1322 unregister_binfmt(&irix_format); 1334 unregister_binfmt(&irix_format);
1323} 1335}
1324 1336