1 /* binfmt_elf_fdpic.c: FDPIC ELF binary format
3 * Copyright (C) 2003, 2004 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 * Derived from binfmt_elf.c
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
13 #include <linux/module.h>
16 #include <linux/stat.h>
17 #include <linux/sched.h>
19 #include <linux/mman.h>
20 #include <linux/errno.h>
21 #include <linux/signal.h>
22 #include <linux/binfmts.h>
23 #include <linux/string.h>
24 #include <linux/file.h>
25 #include <linux/fcntl.h>
26 #include <linux/slab.h>
27 #include <linux/highmem.h>
28 #include <linux/personality.h>
29 #include <linux/ptrace.h>
30 #include <linux/init.h>
31 #include <linux/smp_lock.h>
32 #include <linux/elf.h>
33 #include <linux/elf-fdpic.h>
34 #include <linux/elfcore.h>
35 #include <linux/vs_base.h>
36 #include <linux/vs_cvirt.h>
38 #include <asm/uaccess.h>
39 #include <asm/param.h>
40 #include <asm/pgalloc.h>
42 typedef char *elf_caddr_t;
44 #define elf_addr_t unsigned long
48 #define kdebug(fmt, ...) printk("FDPIC "fmt"\n" ,##__VA_ARGS__ )
50 #define kdebug(fmt, ...) do {} while(0)
53 MODULE_LICENSE("GPL");
55 static int load_elf_fdpic_binary(struct linux_binprm *bprm, struct pt_regs *regs);
56 //static int load_elf_fdpic_library(struct file *);
57 static int elf_fdpic_fetch_phdrs(struct elf_fdpic_params *params, struct file *file);
58 static int elf_fdpic_map_file(struct elf_fdpic_params *params,
63 static int create_elf_fdpic_tables(struct linux_binprm *bprm,
65 struct elf_fdpic_params *exec_params,
66 struct elf_fdpic_params *interp_params);
69 static int elf_fdpic_transfer_args_to_stack(struct linux_binprm *bprm, unsigned long *_sp);
70 static int elf_fdpic_map_file_constdisp_on_uclinux(struct elf_fdpic_params *params,
72 struct mm_struct *mm);
75 static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
77 struct mm_struct *mm);
79 static struct linux_binfmt elf_fdpic_format = {
80 .module = THIS_MODULE,
81 .load_binary = load_elf_fdpic_binary,
82 // .load_shlib = load_elf_fdpic_library,
83 // .core_dump = elf_fdpic_core_dump,
84 .min_coredump = ELF_EXEC_PAGESIZE,
87 static int __init init_elf_fdpic_binfmt(void) { return register_binfmt(&elf_fdpic_format); }
88 static void __exit exit_elf_fdpic_binfmt(void) { unregister_binfmt(&elf_fdpic_format); }
90 module_init(init_elf_fdpic_binfmt)
91 module_exit(exit_elf_fdpic_binfmt)
93 static int is_elf_fdpic(struct elfhdr *hdr, struct file *file)
95 if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0)
97 if (hdr->e_type != ET_EXEC && hdr->e_type != ET_DYN)
99 if (!elf_check_arch(hdr) || !elf_check_fdpic(hdr))
101 if (!file->f_op || !file->f_op->mmap)
106 /*****************************************************************************/
108 * read the program headers table into memory
110 static int elf_fdpic_fetch_phdrs(struct elf_fdpic_params *params, struct file *file)
112 struct elf32_phdr *phdr;
116 if (params->hdr.e_phentsize != sizeof(struct elf_phdr))
118 if (params->hdr.e_phnum > 65536U / sizeof(struct elf_phdr))
121 size = params->hdr.e_phnum * sizeof(struct elf_phdr);
122 params->phdrs = kmalloc(size, GFP_KERNEL);
126 retval = kernel_read(file, params->hdr.e_phoff, (char *) params->phdrs, size);
130 /* determine stack size for this binary */
131 phdr = params->phdrs;
132 for (loop = 0; loop < params->hdr.e_phnum; loop++, phdr++) {
133 if (phdr->p_type != PT_GNU_STACK)
136 if (phdr->p_flags & PF_X)
137 params->flags |= ELF_FDPIC_FLAG_EXEC_STACK;
139 params->flags |= ELF_FDPIC_FLAG_NOEXEC_STACK;
141 params->stack_size = phdr->p_memsz;
146 } /* end elf_fdpic_fetch_phdrs() */
148 /*****************************************************************************/
150 * load an fdpic binary into various bits of memory
152 static int load_elf_fdpic_binary(struct linux_binprm *bprm, struct pt_regs *regs)
154 struct elf_fdpic_params exec_params, interp_params;
155 struct elf_phdr *phdr;
156 unsigned long stack_size;
157 struct file *interpreter = NULL; /* to shut gcc up */
158 char *interpreter_name = NULL;
159 int executable_stack;
162 memset(&exec_params, 0, sizeof(exec_params));
163 memset(&interp_params, 0, sizeof(interp_params));
165 exec_params.hdr = *(struct elfhdr *) bprm->buf;
166 exec_params.flags = ELF_FDPIC_FLAG_PRESENT | ELF_FDPIC_FLAG_EXECUTABLE;
168 /* check that this is a binary we know how to deal with */
170 if (!is_elf_fdpic(&exec_params.hdr, bprm->file))
173 /* read the program header table */
174 retval = elf_fdpic_fetch_phdrs(&exec_params, bprm->file);
178 /* scan for a program header that specifies an interpreter */
179 phdr = exec_params.phdrs;
181 for (i = 0; i < exec_params.hdr.e_phnum; i++, phdr++) {
182 switch (phdr->p_type) {
185 if (phdr->p_filesz > PATH_MAX)
188 if (phdr->p_filesz < 2)
191 /* read the name of the interpreter into memory */
192 interpreter_name = kmalloc(phdr->p_filesz, GFP_KERNEL);
193 if (!interpreter_name)
196 retval = kernel_read(bprm->file,
204 if (interpreter_name[phdr->p_filesz - 1] != '\0')
207 kdebug("Using ELF interpreter %s", interpreter_name);
209 /* replace the program with the interpreter */
210 interpreter = open_exec(interpreter_name);
211 retval = PTR_ERR(interpreter);
212 if (IS_ERR(interpreter)) {
217 retval = kernel_read(interpreter, 0, bprm->buf, BINPRM_BUF_SIZE);
221 interp_params.hdr = *((struct elfhdr *) bprm->buf);
226 if (exec_params.load_addr == 0)
227 exec_params.load_addr = phdr->p_vaddr;
234 if (elf_check_const_displacement(&exec_params.hdr))
235 exec_params.flags |= ELF_FDPIC_FLAG_CONSTDISP;
237 /* perform insanity checks on the interpreter */
238 if (interpreter_name) {
240 if (!is_elf_fdpic(&interp_params.hdr, interpreter))
243 interp_params.flags = ELF_FDPIC_FLAG_PRESENT;
245 /* read the interpreter's program header table */
246 retval = elf_fdpic_fetch_phdrs(&interp_params, interpreter);
251 stack_size = exec_params.stack_size;
252 if (stack_size < interp_params.stack_size)
253 stack_size = interp_params.stack_size;
255 if (exec_params.flags & ELF_FDPIC_FLAG_EXEC_STACK)
256 executable_stack = EXSTACK_ENABLE_X;
257 else if (exec_params.flags & ELF_FDPIC_FLAG_NOEXEC_STACK)
258 executable_stack = EXSTACK_DISABLE_X;
259 else if (interp_params.flags & ELF_FDPIC_FLAG_EXEC_STACK)
260 executable_stack = EXSTACK_ENABLE_X;
261 else if (interp_params.flags & ELF_FDPIC_FLAG_NOEXEC_STACK)
262 executable_stack = EXSTACK_DISABLE_X;
264 executable_stack = EXSTACK_DEFAULT;
270 if (elf_check_const_displacement(&interp_params.hdr))
271 interp_params.flags |= ELF_FDPIC_FLAG_CONSTDISP;
273 /* flush all traces of the currently running executable */
274 retval = flush_old_exec(bprm);
278 /* there's now no turning back... the old userspace image is dead,
279 * defunct, deceased, etc. after this point we have to exit via
281 set_personality(PER_LINUX_FDPIC);
282 set_binfmt(&elf_fdpic_format);
284 current->mm->start_code = 0;
285 current->mm->end_code = 0;
286 current->mm->start_stack = 0;
287 current->mm->start_data = 0;
288 current->mm->end_data = 0;
289 current->mm->context.exec_fdpic_loadmap = 0;
290 current->mm->context.interp_fdpic_loadmap = 0;
292 current->flags &= ~PF_FORKNOEXEC;
295 elf_fdpic_arch_lay_out_mm(&exec_params,
297 ¤t->mm->start_stack,
298 ¤t->mm->start_brk);
300 retval = setup_arg_pages(bprm, current->mm->start_stack, executable_stack);
302 send_sig(SIGKILL, current, 0);
307 /* load the executable and interpreter into memory */
308 retval = elf_fdpic_map_file(&exec_params, bprm->file, current->mm, "executable");
312 if (interpreter_name) {
313 retval = elf_fdpic_map_file(&interp_params, interpreter,
314 current->mm, "interpreter");
316 printk(KERN_ERR "Unable to load interpreter\n");
320 allow_write_access(interpreter);
326 if (!current->mm->start_brk)
327 current->mm->start_brk = current->mm->end_data;
329 current->mm->brk = current->mm->start_brk = PAGE_ALIGN(current->mm->start_brk);
332 /* create a stack and brk area big enough for everyone
333 * - the brk heap starts at the bottom and works up
334 * - the stack starts at the top and works down
336 stack_size = (stack_size + PAGE_SIZE - 1) & PAGE_MASK;
337 if (stack_size < PAGE_SIZE * 2)
338 stack_size = PAGE_SIZE * 2;
340 down_write(¤t->mm->mmap_sem);
341 current->mm->start_brk = do_mmap(NULL,
344 PROT_READ | PROT_WRITE | PROT_EXEC,
345 MAP_PRIVATE | MAP_ANON | MAP_GROWSDOWN,
348 if (IS_ERR((void *) current->mm->start_brk)) {
349 up_write(¤t->mm->mmap_sem);
350 retval = current->mm->start_brk;
351 current->mm->start_brk = 0;
355 if (do_mremap(current->mm->start_brk,
357 ksize((char *) current->mm->start_brk),
359 ) == current->mm->start_brk
361 stack_size = ksize((char *) current->mm->start_brk);
362 up_write(¤t->mm->mmap_sem);
364 current->mm->brk = current->mm->start_brk;
365 current->mm->context.end_brk = current->mm->start_brk;
366 current->mm->context.end_brk += (stack_size > PAGE_SIZE) ? (stack_size - PAGE_SIZE) : 0;
367 current->mm->start_stack = current->mm->start_brk + stack_size;
371 current->flags &= ~PF_FORKNOEXEC;
372 if (create_elf_fdpic_tables(bprm, current->mm, &exec_params, &interp_params) < 0)
375 kdebug("- start_code %lx", (long) current->mm->start_code);
376 kdebug("- end_code %lx", (long) current->mm->end_code);
377 kdebug("- start_data %lx", (long) current->mm->start_data);
378 kdebug("- end_data %lx", (long) current->mm->end_data);
379 kdebug("- start_brk %lx", (long) current->mm->start_brk);
380 kdebug("- brk %lx", (long) current->mm->brk);
381 kdebug("- start_stack %lx", (long) current->mm->start_stack);
383 #ifdef ELF_FDPIC_PLAT_INIT
385 * The ABI may specify that certain registers be set up in special
386 * ways (on i386 %edx is the address of a DT_FINI function, for
387 * example. This macro performs whatever initialization to
388 * the regs structure is required.
390 ELF_FDPIC_PLAT_INIT(regs,
391 exec_params.map_addr,
392 interp_params.map_addr,
393 interp_params.dynamic_addr ?: exec_params.dynamic_addr
397 /* everything is now ready... get the userspace context ready to roll */
399 interp_params.entry_addr ?: exec_params.entry_addr,
400 current->mm->start_stack);
402 if (unlikely(current->ptrace & PT_PTRACED)) {
403 if (current->ptrace & PT_TRACE_EXEC)
404 ptrace_notify ((PTRACE_EVENT_EXEC << 8) | SIGTRAP);
406 send_sig(SIGTRAP, current, 0);
413 allow_write_access(interpreter);
416 kfree(interpreter_name);
417 kfree(exec_params.phdrs);
418 kfree(exec_params.loadmap);
419 kfree(interp_params.phdrs);
420 kfree(interp_params.loadmap);
423 /* unrecoverable error - kill the process */
425 send_sig(SIGSEGV, current, 0);
428 } /* end load_elf_fdpic_binary() */
430 /*****************************************************************************/
432 * present useful information to the program
434 static int create_elf_fdpic_tables(struct linux_binprm *bprm,
435 struct mm_struct *mm,
436 struct elf_fdpic_params *exec_params,
437 struct elf_fdpic_params *interp_params)
439 unsigned long sp, csp, nitems;
440 elf_caddr_t *argv, *envp;
441 size_t platform_len = 0, len;
442 char *k_platform, *u_platform, *p;
446 /* we're going to shovel a whole load of stuff onto the stack */
450 sp = mm->start_stack;
452 /* stack the program arguments and environment */
453 if (elf_fdpic_transfer_args_to_stack(bprm, &sp) < 0)
457 /* get hold of platform and hardware capabilities masks for the machine
458 * we are running on. In some cases (Sparc), this info is impossible
459 * to get, in others (i386) it is merely difficult.
462 k_platform = ELF_PLATFORM;
465 platform_len = strlen(k_platform) + 1;
467 if (__copy_to_user(u_platform, k_platform, platform_len) != 0)
471 u_platform = (char *) sp;
473 #if defined(__i386__) && defined(CONFIG_SMP)
474 /* in some cases (e.g. Hyper-Threading), we want to avoid L1 evictions
475 * by the processes running on the same package. One thing we can do
476 * is to shuffle the initial stack for them.
478 * the conditionals here are unneeded, but kept in to make the
479 * code behaviour the same as pre change unless we have hyperthreaded
480 * processors. This keeps Mr Marcelo Person happier but should be
483 if (smp_num_siblings > 1)
484 sp = sp - ((current->pid % 64) << 7);
489 /* stack the load map(s) */
490 len = sizeof(struct elf32_fdpic_loadmap);
491 len += sizeof(struct elf32_fdpic_loadseg) * exec_params->loadmap->nsegs;
492 sp = (sp - len) & ~7UL;
493 exec_params->map_addr = sp;
495 if (copy_to_user((void *) sp, exec_params->loadmap, len) != 0)
498 current->mm->context.exec_fdpic_loadmap = (unsigned long) sp;
500 if (interp_params->loadmap) {
501 len = sizeof(struct elf32_fdpic_loadmap);
502 len += sizeof(struct elf32_fdpic_loadseg) * interp_params->loadmap->nsegs;
503 sp = (sp - len) & ~7UL;
504 interp_params->map_addr = sp;
506 if (copy_to_user((void *) sp, interp_params->loadmap, len) != 0)
509 current->mm->context.interp_fdpic_loadmap = (unsigned long) sp;
512 /* force 16 byte _final_ alignment here for generality */
513 #define DLINFO_ITEMS 13
515 nitems = 1 + DLINFO_ITEMS + (k_platform ? 1 : 0);
516 #ifdef DLINFO_ARCH_ITEMS
517 nitems += DLINFO_ARCH_ITEMS;
521 sp -= nitems * 2 * sizeof(unsigned long);
522 sp -= (bprm->envc + 1) * sizeof(char *); /* envv[] */
523 sp -= (bprm->argc + 1) * sizeof(char *); /* argv[] */
524 sp -= 1 * sizeof(unsigned long); /* argc */
529 /* put the ELF interpreter info on the stack */
530 #define NEW_AUX_ENT(nr, id, val) \
532 struct { unsigned long _id, _val; } *ent = (void *) csp; \
533 __put_user((id), &ent[nr]._id); \
534 __put_user((val), &ent[nr]._val); \
537 csp -= 2 * sizeof(unsigned long);
538 NEW_AUX_ENT(0, AT_NULL, 0);
540 csp -= 2 * sizeof(unsigned long);
541 NEW_AUX_ENT(0, AT_PLATFORM, (elf_addr_t)(unsigned long) u_platform);
544 csp -= DLINFO_ITEMS * 2 * sizeof(unsigned long);
545 NEW_AUX_ENT( 0, AT_HWCAP, hwcap);
546 NEW_AUX_ENT( 1, AT_PAGESZ, PAGE_SIZE);
547 NEW_AUX_ENT( 2, AT_CLKTCK, CLOCKS_PER_SEC);
548 NEW_AUX_ENT( 3, AT_PHDR, exec_params->ph_addr);
549 NEW_AUX_ENT( 4, AT_PHENT, sizeof(struct elf_phdr));
550 NEW_AUX_ENT( 5, AT_PHNUM, exec_params->hdr.e_phnum);
551 NEW_AUX_ENT( 6, AT_BASE, interp_params->elfhdr_addr);
552 NEW_AUX_ENT( 7, AT_FLAGS, 0);
553 NEW_AUX_ENT( 8, AT_ENTRY, exec_params->entry_addr);
554 NEW_AUX_ENT( 9, AT_UID, (elf_addr_t) current->uid);
555 NEW_AUX_ENT(10, AT_EUID, (elf_addr_t) current->euid);
556 NEW_AUX_ENT(11, AT_GID, (elf_addr_t) current->gid);
557 NEW_AUX_ENT(12, AT_EGID, (elf_addr_t) current->egid);
560 /* ARCH_DLINFO must come last so platform specific code can enforce
561 * special alignment requirements on the AUXV if necessary (eg. PPC).
567 /* allocate room for argv[] and envv[] */
568 csp -= (bprm->envc + 1) * sizeof(elf_caddr_t);
569 envp = (elf_caddr_t *) csp;
570 csp -= (bprm->argc + 1) * sizeof(elf_caddr_t);
571 argv = (elf_caddr_t *) csp;
574 csp -= sizeof(unsigned long);
575 __put_user(bprm->argc, (unsigned long *) csp);
579 /* fill in the argv[] array */
581 current->mm->arg_start = bprm->p;
583 current->mm->arg_start = current->mm->start_stack - (MAX_ARG_PAGES * PAGE_SIZE - bprm->p);
586 p = (char *) current->mm->arg_start;
587 for (loop = bprm->argc; loop > 0; loop--) {
588 __put_user((elf_caddr_t) p, argv++);
589 len = strnlen_user(p, PAGE_SIZE * MAX_ARG_PAGES);
590 if (!len || len > PAGE_SIZE * MAX_ARG_PAGES)
594 __put_user(NULL, argv);
595 current->mm->arg_end = (unsigned long) p;
597 /* fill in the envv[] array */
598 current->mm->env_start = (unsigned long) p;
599 for (loop = bprm->envc; loop > 0; loop--) {
600 __put_user((elf_caddr_t)(unsigned long) p, envp++);
601 len = strnlen_user(p, PAGE_SIZE * MAX_ARG_PAGES);
602 if (!len || len > PAGE_SIZE * MAX_ARG_PAGES)
606 __put_user(NULL, envp);
607 current->mm->env_end = (unsigned long) p;
609 mm->start_stack = (unsigned long) sp;
611 } /* end create_elf_fdpic_tables() */
613 /*****************************************************************************/
615 * transfer the program arguments and environment from the holding pages onto
619 static int elf_fdpic_transfer_args_to_stack(struct linux_binprm *bprm, unsigned long *_sp)
621 unsigned long index, stop, sp;
625 stop = bprm->p >> PAGE_SHIFT;
628 for (index = MAX_ARG_PAGES - 1; index >= stop; index--) {
629 src = kmap(bprm->page[index]);
631 if (copy_to_user((void *) sp, src, PAGE_SIZE) != 0)
633 kunmap(bprm->page[index]);
638 *_sp = (*_sp - (MAX_ARG_PAGES * PAGE_SIZE - bprm->p)) & ~15;
642 } /* end elf_fdpic_transfer_args_to_stack() */
645 /*****************************************************************************/
647 * load the appropriate binary image (executable or interpreter) into memory
648 * - we assume no MMU is available
649 * - if no other PIC bits are set in params->hdr->e_flags
650 * - we assume that the LOADable segments in the binary are independently relocatable
651 * - we assume R/O executable segments are shareable
653 * - we assume the loadable parts of the image to require fixed displacement
654 * - the image is not shareable
656 static int elf_fdpic_map_file(struct elf_fdpic_params *params,
658 struct mm_struct *mm,
661 struct elf32_fdpic_loadmap *loadmap;
663 struct elf32_fdpic_loadseg *mseg;
665 struct elf32_fdpic_loadseg *seg;
666 struct elf32_phdr *phdr;
667 unsigned long load_addr, stop;
668 unsigned nloads, tmp;
672 /* allocate a load map table */
674 for (loop = 0; loop < params->hdr.e_phnum; loop++)
675 if (params->phdrs[loop].p_type == PT_LOAD)
681 size = sizeof(*loadmap) + nloads * sizeof(*seg);
682 loadmap = kmalloc(size, GFP_KERNEL);
686 params->loadmap = loadmap;
687 memset(loadmap, 0, size);
689 loadmap->version = ELF32_FDPIC_LOADMAP_VERSION;
690 loadmap->nsegs = nloads;
692 load_addr = params->load_addr;
695 /* map the requested LOADs into the memory space */
696 switch (params->flags & ELF_FDPIC_FLAG_ARRANGEMENT) {
697 case ELF_FDPIC_FLAG_CONSTDISP:
698 case ELF_FDPIC_FLAG_CONTIGUOUS:
700 ret = elf_fdpic_map_file_constdisp_on_uclinux(params, file, mm);
706 ret = elf_fdpic_map_file_by_direct_mmap(params, file, mm);
712 /* map the entry point */
713 if (params->hdr.e_entry) {
715 for (loop = loadmap->nsegs; loop > 0; loop--, seg++) {
716 if (params->hdr.e_entry >= seg->p_vaddr &&
717 params->hdr.e_entry < seg->p_vaddr + seg->p_memsz
720 (params->hdr.e_entry - seg->p_vaddr) + seg->addr;
726 /* determine where the program header table has wound up if mapped */
727 stop = params->hdr.e_phoff + params->hdr.e_phnum * sizeof (struct elf_phdr);
728 phdr = params->phdrs;
730 for (loop = 0; loop < params->hdr.e_phnum; loop++, phdr++) {
731 if (phdr->p_type != PT_LOAD)
734 if (phdr->p_offset > params->hdr.e_phoff ||
735 phdr->p_offset + phdr->p_filesz < stop)
739 for (loop = loadmap->nsegs; loop > 0; loop--, seg++) {
740 if (phdr->p_vaddr >= seg->p_vaddr &&
741 phdr->p_vaddr + phdr->p_filesz <= seg->p_vaddr + seg->p_memsz
743 params->ph_addr = (phdr->p_vaddr - seg->p_vaddr) + seg->addr +
744 params->hdr.e_phoff - phdr->p_offset;
751 /* determine where the dynamic section has wound up if there is one */
752 phdr = params->phdrs;
753 for (loop = 0; loop < params->hdr.e_phnum; loop++, phdr++) {
754 if (phdr->p_type != PT_DYNAMIC)
758 for (loop = loadmap->nsegs; loop > 0; loop--, seg++) {
759 if (phdr->p_vaddr >= seg->p_vaddr &&
760 phdr->p_vaddr + phdr->p_memsz <= seg->p_vaddr + seg->p_memsz
762 params->dynamic_addr = (phdr->p_vaddr - seg->p_vaddr) + seg->addr;
764 /* check the dynamic section contains at least one item, and that
765 * the last item is a NULL entry */
766 if (phdr->p_memsz == 0 ||
767 phdr->p_memsz % sizeof(Elf32_Dyn) != 0)
770 tmp = phdr->p_memsz / sizeof(Elf32_Dyn);
771 if (((Elf32_Dyn *) params->dynamic_addr)[tmp - 1].d_tag != 0)
779 /* now elide adjacent segments in the load map on MMU linux
780 * - on uClinux the holes between may actually be filled with system stuff or stuff from
784 nloads = loadmap->nsegs;
785 mseg = loadmap->segs;
787 for (loop = 1; loop < nloads; loop++) {
788 /* see if we have a candidate for merging */
789 if (seg->p_vaddr - mseg->p_vaddr == seg->addr - mseg->addr) {
790 load_addr = PAGE_ALIGN(mseg->addr + mseg->p_memsz);
791 if (load_addr == (seg->addr & PAGE_MASK)) {
792 mseg->p_memsz += load_addr - (mseg->addr + mseg->p_memsz);
793 mseg->p_memsz += seg->addr & ~PAGE_MASK;
794 mseg->p_memsz += seg->p_memsz;
806 kdebug("Mapped Object [%s]:", what);
807 kdebug("- elfhdr : %lx", params->elfhdr_addr);
808 kdebug("- entry : %lx", params->entry_addr);
809 kdebug("- PHDR[] : %lx", params->ph_addr);
810 kdebug("- DYNAMIC[]: %lx", params->dynamic_addr);
812 for (loop = 0; loop < loadmap->nsegs; loop++, seg++)
813 kdebug("- LOAD[%d] : %08x-%08x [va=%x ms=%x]",
815 seg->addr, seg->addr + seg->p_memsz - 1,
816 seg->p_vaddr, seg->p_memsz);
821 printk("ELF FDPIC %s with invalid DYNAMIC section (inode=%lu)\n",
822 what, file->f_dentry->d_inode->i_ino);
824 } /* end elf_fdpic_map_file() */
826 /*****************************************************************************/
828 * map a file with constant displacement under uClinux
831 static int elf_fdpic_map_file_constdisp_on_uclinux(struct elf_fdpic_params *params,
833 struct mm_struct *mm)
835 struct elf32_fdpic_loadseg *seg;
836 struct elf32_phdr *phdr;
837 unsigned long load_addr, base = ULONG_MAX, top = 0, maddr = 0, mflags;
841 load_addr = params->load_addr;
842 seg = params->loadmap->segs;
844 /* determine the bounds of the contiguous overall allocation we must make */
845 phdr = params->phdrs;
846 for (loop = 0; loop < params->hdr.e_phnum; loop++, phdr++) {
847 if (params->phdrs[loop].p_type != PT_LOAD)
850 if (base > phdr->p_vaddr)
851 base = phdr->p_vaddr;
852 if (top < phdr->p_vaddr + phdr->p_memsz)
853 top = phdr->p_vaddr + phdr->p_memsz;
856 /* allocate one big anon block for everything */
857 mflags = MAP_PRIVATE;
858 if (params->flags & ELF_FDPIC_FLAG_EXECUTABLE)
859 mflags |= MAP_EXECUTABLE;
861 down_write(&mm->mmap_sem);
862 maddr = do_mmap(NULL, load_addr, top - base,
863 PROT_READ | PROT_WRITE | PROT_EXEC, mflags, 0);
864 up_write(&mm->mmap_sem);
865 if (IS_ERR((void *) maddr))
869 load_addr += PAGE_ALIGN(top - base);
871 /* and then load the file segments into it */
872 phdr = params->phdrs;
873 for (loop = 0; loop < params->hdr.e_phnum; loop++, phdr++) {
874 if (params->phdrs[loop].p_type != PT_LOAD)
877 fpos = phdr->p_offset;
879 seg->addr = maddr + (phdr->p_vaddr - base);
880 seg->p_vaddr = phdr->p_vaddr;
881 seg->p_memsz = phdr->p_memsz;
883 ret = file->f_op->read(file, (void *) seg->addr, phdr->p_filesz, &fpos);
887 /* map the ELF header address if in this segment */
888 if (phdr->p_offset == 0)
889 params->elfhdr_addr = seg->addr;
891 /* clear any space allocated but not loaded */
892 if (phdr->p_filesz < phdr->p_memsz)
893 clear_user((void *) (seg->addr + phdr->p_filesz),
894 phdr->p_memsz - phdr->p_filesz);
897 if (phdr->p_flags & PF_X) {
898 mm->start_code = seg->addr;
899 mm->end_code = seg->addr + phdr->p_memsz;
901 else if (!mm->start_data) {
902 mm->start_data = seg->addr;
904 mm->end_data = seg->addr + phdr->p_memsz;
909 if (seg->addr + phdr->p_memsz > mm->end_data)
910 mm->end_data = seg->addr + phdr->p_memsz;
918 } /* end elf_fdpic_map_file_constdisp_on_uclinux() */
921 /*****************************************************************************/
923 * map a binary by direct mmap() of the individual PT_LOAD segments
925 static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
927 struct mm_struct *mm)
929 struct elf32_fdpic_loadseg *seg;
930 struct elf32_phdr *phdr;
931 unsigned long load_addr, delta_vaddr;
934 load_addr = params->load_addr;
938 seg = params->loadmap->segs;
940 /* deal with each load segment separately */
941 phdr = params->phdrs;
942 for (loop = 0; loop < params->hdr.e_phnum; loop++, phdr++) {
943 unsigned long maddr, disp, excess, excess1;
946 if (phdr->p_type != PT_LOAD)
949 kdebug("[LOAD] va=%lx of=%lx fs=%lx ms=%lx",
950 (unsigned long) phdr->p_vaddr,
951 (unsigned long) phdr->p_offset,
952 (unsigned long) phdr->p_filesz,
953 (unsigned long) phdr->p_memsz);
955 /* determine the mapping parameters */
956 if (phdr->p_flags & PF_R) prot |= PROT_READ;
957 if (phdr->p_flags & PF_W) prot |= PROT_WRITE;
958 if (phdr->p_flags & PF_X) prot |= PROT_EXEC;
960 flags = MAP_PRIVATE | MAP_DENYWRITE;
961 if (params->flags & ELF_FDPIC_FLAG_EXECUTABLE)
962 flags |= MAP_EXECUTABLE;
966 switch (params->flags & ELF_FDPIC_FLAG_ARRANGEMENT) {
967 case ELF_FDPIC_FLAG_INDEPENDENT:
968 /* PT_LOADs are independently locatable */
971 case ELF_FDPIC_FLAG_HONOURVADDR:
972 /* the specified virtual address must be honoured */
973 maddr = phdr->p_vaddr;
977 case ELF_FDPIC_FLAG_CONSTDISP:
978 /* constant displacement
979 * - can be mapped anywhere, but must be mapped as a unit
983 delta_vaddr = phdr->p_vaddr;
987 maddr = load_addr + phdr->p_vaddr - delta_vaddr;
992 case ELF_FDPIC_FLAG_CONTIGUOUS:
993 /* contiguity handled later */
1002 /* create the mapping */
1003 disp = phdr->p_vaddr & ~PAGE_MASK;
1004 down_write(&mm->mmap_sem);
1005 maddr = do_mmap(file, maddr, phdr->p_memsz + disp, prot, flags,
1006 phdr->p_offset - disp);
1007 up_write(&mm->mmap_sem);
1009 kdebug("mmap[%d] <file> sz=%lx pr=%x fl=%x of=%lx --> %08lx",
1010 loop, phdr->p_memsz + disp, prot, flags, phdr->p_offset - disp,
1013 if (IS_ERR((void *) maddr))
1016 if ((params->flags & ELF_FDPIC_FLAG_ARRANGEMENT) == ELF_FDPIC_FLAG_CONTIGUOUS)
1017 load_addr += PAGE_ALIGN(phdr->p_memsz + disp);
1019 seg->addr = maddr + disp;
1020 seg->p_vaddr = phdr->p_vaddr;
1021 seg->p_memsz = phdr->p_memsz;
1023 /* map the ELF header address if in this segment */
1024 if (phdr->p_offset == 0)
1025 params->elfhdr_addr = seg->addr;
1027 /* clear the bit between beginning of mapping and beginning of PT_LOAD */
1028 if (prot & PROT_WRITE && disp > 0) {
1029 kdebug("clear[%d] ad=%lx sz=%lx", loop, maddr, disp);
1030 clear_user((void *) maddr, disp);
1034 /* clear any space allocated but not loaded
1035 * - on uClinux we can just clear the lot
1036 * - on MMU linux we'll get a SIGBUS beyond the last page
1037 * extant in the file
1039 excess = phdr->p_memsz - phdr->p_filesz;
1040 excess1 = PAGE_SIZE - ((maddr + phdr->p_filesz) & ~PAGE_MASK);
1044 if (excess > excess1) {
1045 unsigned long xaddr = maddr + phdr->p_filesz + excess1;
1046 unsigned long xmaddr;
1048 flags |= MAP_FIXED | MAP_ANONYMOUS;
1049 down_write(&mm->mmap_sem);
1050 xmaddr = do_mmap(NULL, xaddr, excess - excess1, prot, flags, 0);
1051 up_write(&mm->mmap_sem);
1053 kdebug("mmap[%d] <anon>"
1054 " ad=%lx sz=%lx pr=%x fl=%x of=0 --> %08lx",
1055 loop, xaddr, excess - excess1, prot, flags, xmaddr);
1057 if (xmaddr != xaddr)
1061 if (prot & PROT_WRITE && excess1 > 0) {
1062 kdebug("clear[%d] ad=%lx sz=%lx",
1063 loop, maddr + phdr->p_filesz, excess1);
1064 clear_user((void *) maddr + phdr->p_filesz, excess1);
1069 kdebug("clear[%d] ad=%lx sz=%lx",
1070 loop, maddr + phdr->p_filesz, excess);
1071 clear_user((void *) maddr + phdr->p_filesz, excess);
1076 if (phdr->p_flags & PF_X) {
1077 mm->start_code = maddr;
1078 mm->end_code = maddr + phdr->p_memsz;
1080 else if (!mm->start_data) {
1081 mm->start_data = maddr;
1082 mm->end_data = maddr + phdr->p_memsz;
1090 } /* end elf_fdpic_map_file_by_direct_mmap() */