~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/fs/binfmt_elf.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * linux/fs/binfmt_elf.c
  3  *
  4  * These are the functions used to load ELF format executables as used
  5  * on SVr4 machines.  Information on the format may be found in the book
  6  * "UNIX SYSTEM V RELEASE 4 Programmers Guide: Ansi C and Programming Support
  7  * Tools".
  8  *
  9  * Copyright 1993, 1994: Eric Youngdale (ericy@cais.com).
 10  */
 11 
 12 #include <linux/module.h>
 13 
 14 #include <linux/fs.h>
 15 #include <linux/stat.h>
 16 #include <linux/sched.h>
 17 #include <linux/mm.h>
 18 #include <linux/mman.h>
 19 #include <linux/a.out.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/ptrace.h>
 27 #include <linux/malloc.h>
 28 #include <linux/shm.h>
 29 #include <linux/personality.h>
 30 #include <linux/elfcore.h>
 31 #include <linux/init.h>
 32 #include <linux/highuid.h>
 33 #include <linux/smp_lock.h>
 34 
 35 #include <asm/uaccess.h>
 36 #include <asm/param.h>
 37 #include <asm/pgalloc.h>
 38 
 39 #define DLINFO_ITEMS 13
 40 
 41 #include <linux/elf.h>
 42 
 43 static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs);
 44 static int load_elf_library(struct file*);
 45 static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int);
 46 extern int dump_fpu (struct pt_regs *, elf_fpregset_t *);
 47 extern void dump_thread(struct pt_regs *, struct user *);
 48 
 49 #ifndef elf_addr_t
 50 #define elf_addr_t unsigned long
 51 #define elf_caddr_t char *
 52 #endif
 53 
 54 /*
 55  * If we don't support core dumping, then supply a NULL so we
 56  * don't even try.
 57  */
 58 #ifdef USE_ELF_CORE_DUMP
 59 static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file);
 60 #else
 61 #define elf_core_dump   NULL
 62 #endif
 63 
 64 #if ELF_EXEC_PAGESIZE > PAGE_SIZE
 65 # define ELF_MIN_ALIGN  ELF_EXEC_PAGESIZE
 66 #else
 67 # define ELF_MIN_ALIGN  PAGE_SIZE
 68 #endif
 69 
 70 #define ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(ELF_MIN_ALIGN-1))
 71 #define ELF_PAGEOFFSET(_v) ((_v) & (ELF_MIN_ALIGN-1))
 72 #define ELF_PAGEALIGN(_v) (((_v) + ELF_MIN_ALIGN - 1) & ~(ELF_MIN_ALIGN - 1))
 73 
 74 static struct linux_binfmt elf_format = {
 75         NULL, THIS_MODULE, load_elf_binary, load_elf_library, elf_core_dump, ELF_EXEC_PAGESIZE
 76 };
 77 
 78 static void set_brk(unsigned long start, unsigned long end)
 79 {
 80         start = ELF_PAGEALIGN(start);
 81         end = ELF_PAGEALIGN(end);
 82         if (end <= start)
 83                 return;
 84         do_brk(start, end - start);
 85 }
 86 
 87 
 88 /* We need to explicitly zero any fractional pages
 89    after the data section (i.e. bss).  This would
 90    contain the junk from the file that should not
 91    be in memory */
 92 
 93 
 94 static void padzero(unsigned long elf_bss)
 95 {
 96         unsigned long nbyte;
 97 
 98         nbyte = ELF_PAGEOFFSET(elf_bss);
 99         if (nbyte) {
100                 nbyte = ELF_MIN_ALIGN - nbyte;
101                 clear_user((void *) elf_bss, nbyte);
102         }
103 }
104 
105 static elf_addr_t * 
106 create_elf_tables(char *p, int argc, int envc,
107                   struct elfhdr * exec,
108                   unsigned long load_addr,
109                   unsigned long load_bias,
110                   unsigned long interp_load_addr, int ibcs)
111 {
112         elf_caddr_t *argv;
113         elf_caddr_t *envp;
114         elf_addr_t *sp, *csp;
115         char *k_platform, *u_platform;
116         long hwcap;
117         size_t platform_len = 0;
118 
119         /*
120          * Get hold of platform and hardware capabilities masks for
121          * the machine we are running on.  In some cases (Sparc), 
122          * this info is impossible to get, in others (i386) it is
123          * merely difficult.
124          */
125 
126         hwcap = ELF_HWCAP;
127         k_platform = ELF_PLATFORM;
128 
129         if (k_platform) {
130                 platform_len = strlen(k_platform) + 1;
131                 u_platform = p - platform_len;
132                 __copy_to_user(u_platform, k_platform, platform_len);
133         } else
134                 u_platform = p;
135 
136         /*
137          * Force 16 byte _final_ alignment here for generality.
138          * Leave an extra 16 bytes free so that on the PowerPC we
139          * can move the aux table up to start on a 16-byte boundary.
140          */
141         sp = (elf_addr_t *)((~15UL & (unsigned long)(u_platform)) - 16UL);
142         csp = sp;
143         csp -= ((exec ? DLINFO_ITEMS*2 : 4) + (k_platform ? 2 : 0));
144         csp -= envc+1;
145         csp -= argc+1;
146         csp -= (!ibcs ? 3 : 1); /* argc itself */
147         if ((unsigned long)csp & 15UL)
148                 sp -= ((unsigned long)csp & 15UL) / sizeof(*sp);
149 
150         /*
151          * Put the ELF interpreter info on the stack
152          */
153 #define NEW_AUX_ENT(nr, id, val) \
154           __put_user ((id), sp+(nr*2)); \
155           __put_user ((val), sp+(nr*2+1)); \
156 
157         sp -= 2;
158         NEW_AUX_ENT(0, AT_NULL, 0);
159         if (k_platform) {
160                 sp -= 2;
161                 NEW_AUX_ENT(0, AT_PLATFORM, (elf_addr_t)(unsigned long) u_platform);
162         }
163         sp -= 3*2;
164         NEW_AUX_ENT(0, AT_HWCAP, hwcap);
165         NEW_AUX_ENT(1, AT_PAGESZ, ELF_EXEC_PAGESIZE);
166         NEW_AUX_ENT(2, AT_CLKTCK, CLOCKS_PER_SEC);
167 
168         if (exec) {
169                 sp -= 10*2;
170 
171                 NEW_AUX_ENT(0, AT_PHDR, load_addr + exec->e_phoff);
172                 NEW_AUX_ENT(1, AT_PHENT, sizeof (struct elf_phdr));
173                 NEW_AUX_ENT(2, AT_PHNUM, exec->e_phnum);
174                 NEW_AUX_ENT(3, AT_BASE, interp_load_addr);
175                 NEW_AUX_ENT(4, AT_FLAGS, 0);
176                 NEW_AUX_ENT(5, AT_ENTRY, load_bias + exec->e_entry);
177                 NEW_AUX_ENT(6, AT_UID, (elf_addr_t) current->uid);
178                 NEW_AUX_ENT(7, AT_EUID, (elf_addr_t) current->euid);
179                 NEW_AUX_ENT(8, AT_GID, (elf_addr_t) current->gid);
180                 NEW_AUX_ENT(9, AT_EGID, (elf_addr_t) current->egid);
181         }
182 #undef NEW_AUX_ENT
183 
184         sp -= envc+1;
185         envp = (elf_caddr_t *) sp;
186         sp -= argc+1;
187         argv = (elf_caddr_t *) sp;
188         if (!ibcs) {
189                 __put_user((elf_addr_t)(unsigned long) envp,--sp);
190                 __put_user((elf_addr_t)(unsigned long) argv,--sp);
191         }
192 
193         __put_user((elf_addr_t)argc,--sp);
194         current->mm->arg_start = (unsigned long) p;
195         while (argc-->0) {
196                 __put_user((elf_caddr_t)(unsigned long)p,argv++);
197                 p += strlen_user(p);
198         }
199         __put_user(NULL, argv);
200         current->mm->arg_end = current->mm->env_start = (unsigned long) p;
201         while (envc-->0) {
202                 __put_user((elf_caddr_t)(unsigned long)p,envp++);
203                 p += strlen_user(p);
204         }
205         __put_user(NULL, envp);
206         current->mm->env_end = (unsigned long) p;
207         return sp;
208 }
209 
210 #ifndef elf_map
211 
212 static inline unsigned long
213 elf_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type)
214 {
215         unsigned long map_addr;
216 
217         down(&current->mm->mmap_sem);
218         map_addr = do_mmap(filep, ELF_PAGESTART(addr),
219                            eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr), prot, type,
220                            eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr));
221         up(&current->mm->mmap_sem);
222         return(map_addr);
223 }
224 
225 #endif /* !elf_map */
226 
227 /* This is much more generalized than the library routine read function,
228    so we keep this separate.  Technically the library read function
229    is only provided so that we can read a.out libraries that have
230    an ELF header */
231 
232 static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
233                                      struct file * interpreter,
234                                      unsigned long *interp_load_addr)
235 {
236         struct elf_phdr *elf_phdata;
237         struct elf_phdr *eppnt;
238         unsigned long load_addr = 0;
239         int load_addr_set = 0;
240         unsigned long last_bss = 0, elf_bss = 0;
241         unsigned long error = ~0UL;
242         int retval, i, size;
243 
244         /* First of all, some simple consistency checks */
245         if (interp_elf_ex->e_type != ET_EXEC &&
246             interp_elf_ex->e_type != ET_DYN)
247                 goto out;
248         if (!elf_check_arch(interp_elf_ex))
249                 goto out;
250         if (!interpreter->f_op || !interpreter->f_op->mmap)
251                 goto out;
252 
253         /*
254          * If the size of this structure has changed, then punt, since
255          * we will be doing the wrong thing.
256          */
257         if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr))
258                 goto out;
259 
260         /* Now read in all of the header information */
261 
262         size = sizeof(struct elf_phdr) * interp_elf_ex->e_phnum;
263         if (size > ELF_MIN_ALIGN)
264                 goto out;
265         elf_phdata = (struct elf_phdr *) kmalloc(size, GFP_KERNEL);
266         if (!elf_phdata)
267                 goto out;
268 
269         retval = kernel_read(interpreter,interp_elf_ex->e_phoff,(char *)elf_phdata,size);
270         error = retval;
271         if (retval < 0)
272                 goto out_close;
273 
274         eppnt = elf_phdata;
275         for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
276           if (eppnt->p_type == PT_LOAD) {
277             int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
278             int elf_prot = 0;
279             unsigned long vaddr = 0;
280             unsigned long k, map_addr;
281 
282             if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
283             if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
284             if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
285             vaddr = eppnt->p_vaddr;
286             if (interp_elf_ex->e_type == ET_EXEC || load_addr_set)
287                 elf_type |= MAP_FIXED;
288 
289             map_addr = elf_map(interpreter, load_addr + vaddr, eppnt, elf_prot, elf_type);
290 
291             if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
292                 load_addr = map_addr - ELF_PAGESTART(vaddr);
293                 load_addr_set = 1;
294             }
295 
296             /*
297              * Find the end of the file mapping for this phdr, and keep
298              * track of the largest address we see for this.
299              */
300             k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
301             if (k > elf_bss)
302                 elf_bss = k;
303 
304             /*
305              * Do the same thing for the memory mapping - between
306              * elf_bss and last_bss is the bss section.
307              */
308             k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
309             if (k > last_bss)
310                 last_bss = k;
311           }
312         }
313 
314         /* Now use mmap to map the library into memory. */
315 
316         /*
317          * Now fill out the bss section.  First pad the last page up
318          * to the page boundary, and then perform a mmap to make sure
319          * that there are zero-mapped pages up to and including the 
320          * last bss page.
321          */
322         padzero(elf_bss);
323         elf_bss = ELF_PAGESTART(elf_bss + ELF_MIN_ALIGN - 1);   /* What we have mapped so far */
324 
325         /* Map the last of the bss segment */
326         if (last_bss > elf_bss)
327                 do_brk(elf_bss, last_bss - elf_bss);
328 
329         *interp_load_addr = load_addr;
330         error = ((unsigned long) interp_elf_ex->e_entry) + load_addr;
331 
332 out_close:
333         kfree(elf_phdata);
334 out:
335         return error;
336 }
337 
338 static unsigned long load_aout_interp(struct exec * interp_ex,
339                              struct file * interpreter)
340 {
341         unsigned long text_data, elf_entry = ~0UL;
342         char * addr;
343         loff_t offset;
344         int retval;
345 
346         current->mm->end_code = interp_ex->a_text;
347         text_data = interp_ex->a_text + interp_ex->a_data;
348         current->mm->end_data = text_data;
349         current->mm->brk = interp_ex->a_bss + text_data;
350 
351         switch (N_MAGIC(*interp_ex)) {
352         case OMAGIC:
353                 offset = 32;
354                 addr = (char *) 0;
355                 break;
356         case ZMAGIC:
357         case QMAGIC:
358                 offset = N_TXTOFF(*interp_ex);
359                 addr = (char *) N_TXTADDR(*interp_ex);
360                 break;
361         default:
362                 goto out;
363         }
364 
365         do_brk(0, text_data);
366         retval = -ENOEXEC;
367         if (!interpreter->f_op || !interpreter->f_op->read)
368                 goto out;
369         retval = interpreter->f_op->read(interpreter, addr, text_data, &offset);
370         if (retval < 0)
371                 goto out;
372         flush_icache_range((unsigned long)addr,
373                            (unsigned long)addr + text_data);
374 
375         do_brk(ELF_PAGESTART(text_data + ELF_MIN_ALIGN - 1),
376                 interp_ex->a_bss);
377         elf_entry = interp_ex->a_entry;
378 
379 out:
380         return elf_entry;
381 }
382 
383 /*
384  * These are the functions used to load ELF style executables and shared
385  * libraries.  There is no binary dependent code anywhere else.
386  */
387 
388 #define INTERPRETER_NONE 0
389 #define INTERPRETER_AOUT 1
390 #define INTERPRETER_ELF 2
391 
392 
393 static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
394 {
395         struct file *interpreter = NULL; /* to shut gcc up */
396         unsigned long load_addr = 0, load_bias;
397         int load_addr_set = 0;
398         char * elf_interpreter = NULL;
399         unsigned int interpreter_type = INTERPRETER_NONE;
400         unsigned char ibcs2_interpreter = 0;
401         mm_segment_t old_fs;
402         unsigned long error;
403         struct elf_phdr * elf_ppnt, *elf_phdata;
404         unsigned long elf_bss, k, elf_brk;
405         int elf_exec_fileno;
406         int retval, size, i;
407         unsigned long elf_entry, interp_load_addr = 0;
408         unsigned long start_code, end_code, start_data, end_data;
409         struct elfhdr elf_ex;
410         struct elfhdr interp_elf_ex;
411         struct exec interp_ex;
412         char passed_fileno[6];
413 
414         /* Get the exec-header */
415         elf_ex = *((struct elfhdr *) bprm->buf);
416 
417         retval = -ENOEXEC;
418         /* First of all, some simple consistency checks */
419         if (memcmp(elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
420                 goto out;
421 
422         if (elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN)
423                 goto out;
424         if (!elf_check_arch(&elf_ex))
425                 goto out;
426         if (!bprm->file->f_op||!bprm->file->f_op->mmap)
427                 goto out;
428 
429         /* Now read in all of the header information */
430 
431         retval = -ENOMEM;
432         size = elf_ex.e_phentsize * elf_ex.e_phnum;
433         if (size > 65536)
434                 goto out;
435         elf_phdata = (struct elf_phdr *) kmalloc(size, GFP_KERNEL);
436         if (!elf_phdata)
437                 goto out;
438 
439         retval = kernel_read(bprm->file, elf_ex.e_phoff, (char *) elf_phdata, size);
440         if (retval < 0)
441                 goto out_free_ph;
442 
443         retval = get_unused_fd();
444         if (retval < 0)
445                 goto out_free_ph;
446         get_file(bprm->file);
447         fd_install(elf_exec_fileno = retval, bprm->file);
448 
449         elf_ppnt = elf_phdata;
450         elf_bss = 0;
451         elf_brk = 0;
452 
453         start_code = ~0UL;
454         end_code = 0;
455         start_data = 0;
456         end_data = 0;
457 
458         for (i = 0; i < elf_ex.e_phnum; i++) {
459                 if (elf_ppnt->p_type == PT_INTERP) {
460                         retval = -EINVAL;
461                         if (elf_interpreter)
462                                 goto out_free_dentry;
463 
464                         /* This is the program interpreter used for
465                          * shared libraries - for now assume that this
466                          * is an a.out format binary
467                          */
468 
469                         retval = -ENOMEM;
470                         elf_interpreter = (char *) kmalloc(elf_ppnt->p_filesz,
471                                                            GFP_KERNEL);
472                         if (!elf_interpreter)
473                                 goto out_free_file;
474 
475                         retval = kernel_read(bprm->file, elf_ppnt->p_offset,
476                                            elf_interpreter,
477                                            elf_ppnt->p_filesz);
478                         if (retval < 0)
479                                 goto out_free_interp;
480                         /* If the program interpreter is one of these two,
481                          * then assume an iBCS2 image. Otherwise assume
482                          * a native linux image.
483                          */
484                         if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||
485                             strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0)
486                                 ibcs2_interpreter = 1;
487 #if 0
488                         printk("Using ELF interpreter %s\n", elf_interpreter);
489 #endif
490 #ifdef __sparc__
491                         if (ibcs2_interpreter) {
492                                 unsigned long old_pers = current->personality;
493                                 struct exec_domain *old_domain = current->exec_domain;
494                                 struct exec_domain *new_domain;
495                                 struct fs_struct *old_fs = current->fs, *new_fs;
496                                 get_exec_domain(old_domain);
497                                 atomic_inc(&old_fs->count);
498 
499                                 set_personality(PER_SVR4);
500                                 interpreter = open_exec(elf_interpreter);
501 
502                                 new_domain = current->exec_domain;
503                                 new_fs = current->fs;
504                                 current->personality = old_pers;
505                                 current->exec_domain = old_domain;
506                                 current->fs = old_fs;
507                                 put_exec_domain(new_domain);
508                                 put_fs_struct(new_fs);
509                         } else
510 #endif
511                         {
512                                 interpreter = open_exec(elf_interpreter);
513                         }
514                         retval = PTR_ERR(interpreter);
515                         if (IS_ERR(interpreter))
516                                 goto out_free_interp;
517                         retval = kernel_read(interpreter, 0, bprm->buf, BINPRM_BUF_SIZE);
518                         if (retval < 0)
519                                 goto out_free_dentry;
520 
521                         /* Get the exec headers */
522                         interp_ex = *((struct exec *) bprm->buf);
523                         interp_elf_ex = *((struct elfhdr *) bprm->buf);
524                 }
525                 elf_ppnt++;
526         }
527 
528         /* Some simple consistency checks for the interpreter */
529         if (elf_interpreter) {
530                 interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
531 
532                 /* Now figure out which format our binary is */
533                 if ((N_MAGIC(interp_ex) != OMAGIC) &&
534                     (N_MAGIC(interp_ex) != ZMAGIC) &&
535                     (N_MAGIC(interp_ex) != QMAGIC))
536                         interpreter_type = INTERPRETER_ELF;
537 
538                 if (memcmp(interp_elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
539                         interpreter_type &= ~INTERPRETER_ELF;
540 
541                 retval = -ELIBBAD;
542                 if (!interpreter_type)
543                         goto out_free_dentry;
544 
545                 /* Make sure only one type was selected */
546                 if ((interpreter_type & INTERPRETER_ELF) &&
547                      interpreter_type != INTERPRETER_ELF) {
548                         printk(KERN_WARNING "ELF: Ambiguous type, using ELF\n");
549                         interpreter_type = INTERPRETER_ELF;
550                 }
551         }
552 
553         /* OK, we are done with that, now set up the arg stuff,
554            and then start this sucker up */
555 
556         if (!bprm->sh_bang) {
557                 char * passed_p;
558 
559                 if (interpreter_type == INTERPRETER_AOUT) {
560                   sprintf(passed_fileno, "%d", elf_exec_fileno);
561                   passed_p = passed_fileno;
562 
563                   if (elf_interpreter) {
564                     retval = copy_strings_kernel(1,&passed_p,bprm);
565                         if (retval)
566                                 goto out_free_dentry; 
567                     bprm->argc++;
568                   }
569                 }
570         }
571 
572         /* Flush all traces of the currently running executable */
573         retval = flush_old_exec(bprm);
574         if (retval)
575                 goto out_free_dentry;
576 
577         /* OK, This is the point of no return */
578         current->mm->start_data = 0;
579         current->mm->end_data = 0;
580         current->mm->end_code = 0;
581         current->mm->mmap = NULL;
582         current->flags &= ~PF_FORKNOEXEC;
583         elf_entry = (unsigned long) elf_ex.e_entry;
584 
585         /* Do this immediately, since STACK_TOP as used in setup_arg_pages
586            may depend on the personality.  */
587         SET_PERSONALITY(elf_ex, ibcs2_interpreter);
588 
589         /* Do this so that we can load the interpreter, if need be.  We will
590            change some of these later */
591         current->mm->rss = 0;
592         setup_arg_pages(bprm); /* XXX: check error */
593         current->mm->start_stack = bprm->p;
594 
595         /* Try and get dynamic programs out of the way of the default mmap
596            base, as well as whatever program they might try to exec.  This
597            is because the brk will follow the loader, and is not movable.  */
598 
599         load_bias = ELF_PAGESTART(elf_ex.e_type==ET_DYN ? ELF_ET_DYN_BASE : 0);
600 
601         /* Now we do a little grungy work by mmaping the ELF image into
602            the correct location in memory.  At this point, we assume that
603            the image should be loaded at fixed address, not at a variable
604            address. */
605 
606         old_fs = get_fs();
607         set_fs(get_ds());
608         for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
609                 int elf_prot = 0, elf_flags;
610                 unsigned long vaddr;
611 
612                 if (elf_ppnt->p_type != PT_LOAD)
613                         continue;
614 
615                 if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
616                 if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
617                 if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
618 
619                 elf_flags = MAP_PRIVATE|MAP_DENYWRITE|MAP_EXECUTABLE;
620 
621                 vaddr = elf_ppnt->p_vaddr;
622                 if (elf_ex.e_type == ET_EXEC || load_addr_set) {
623                         elf_flags |= MAP_FIXED;
624                 }
625 
626                 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
627 
628                 if (!load_addr_set) {
629                         load_addr_set = 1;
630                         load_addr = (elf_ppnt->p_vaddr - elf_ppnt->p_offset);
631                         if (elf_ex.e_type == ET_DYN) {
632                                 load_bias += error -
633                                              ELF_PAGESTART(load_bias + vaddr);
634                                 load_addr += error;
635                         }
636                 }
637                 k = elf_ppnt->p_vaddr;
638                 if (k < start_code) start_code = k;
639                 if (start_data < k) start_data = k;
640 
641                 k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
642 
643                 if (k > elf_bss)
644                         elf_bss = k;
645                 if ((elf_ppnt->p_flags & PF_X) && end_code <  k)
646                         end_code = k;
647                 if (end_data < k)
648                         end_data = k;
649                 k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
650                 if (k > elf_brk)
651                         elf_brk = k;
652         }
653         set_fs(old_fs);
654 
655         elf_entry += load_bias;
656         elf_bss += load_bias;
657         elf_brk += load_bias;
658         start_code += load_bias;
659         end_code += load_bias;
660         start_data += load_bias;
661         end_data += load_bias;
662 
663         if (elf_interpreter) {
664                 if (interpreter_type == INTERPRETER_AOUT)
665                         elf_entry = load_aout_interp(&interp_ex,
666                                                      interpreter);
667                 else
668                         elf_entry = load_elf_interp(&interp_elf_ex,
669                                                     interpreter,
670                                                     &interp_load_addr);
671 
672                 allow_write_access(interpreter);
673                 fput(interpreter);
674                 kfree(elf_interpreter);
675 
676                 if (elf_entry == ~0UL) {
677                         printk(KERN_ERR "Unable to load interpreter\n");
678                         kfree(elf_phdata);
679                         send_sig(SIGSEGV, current, 0);
680                         return 0;
681                 }
682         }
683 
684         kfree(elf_phdata);
685 
686         if (interpreter_type != INTERPRETER_AOUT)
687                 sys_close(elf_exec_fileno);
688 
689         set_binfmt(&elf_format);
690 
691         compute_creds(bprm);
692         current->flags &= ~PF_FORKNOEXEC;
693         bprm->p = (unsigned long)
694           create_elf_tables((char *)bprm->p,
695                         bprm->argc,
696                         bprm->envc,
697                         (interpreter_type == INTERPRETER_ELF ? &elf_ex : NULL),
698                         load_addr, load_bias,
699                         interp_load_addr,
700                         (interpreter_type == INTERPRETER_AOUT ? 0 : 1));
701         /* N.B. passed_fileno might not be initialized? */
702         if (interpreter_type == INTERPRETER_AOUT)
703                 current->mm->arg_start += strlen(passed_fileno) + 1;
704         current->mm->start_brk = current->mm->brk = elf_brk;
705         current->mm->end_code = end_code;
706         current->mm->start_code = start_code;
707         current->mm->start_data = start_data;
708         current->mm->end_data = end_data;
709         current->mm->start_stack = bprm->p;
710 
711         /* Calling set_brk effectively mmaps the pages that we need
712          * for the bss and break sections
713          */
714         set_brk(elf_bss, elf_brk);
715 
716         padzero(elf_bss);
717 
718 #if 0
719         printk("(start_brk) %lx\n" , (long) current->mm->start_brk);
720         printk("(end_code) %lx\n" , (long) current->mm->end_code);
721         printk("(start_code) %lx\n" , (long) current->mm->start_code);
722         printk("(start_data) %lx\n" , (long) current->mm->start_data);
723         printk("(end_data) %lx\n" , (long) current->mm->end_data);
724         printk("(start_stack) %lx\n" , (long) current->mm->start_stack);
725         printk("(brk) %lx\n" , (long) current->mm->brk);
726 #endif
727 
728         if ( current->personality == PER_SVR4 )
729         {
730                 /* Why this, you ask???  Well SVr4 maps page 0 as read-only,
731                    and some applications "depend" upon this behavior.
732                    Since we do not have the power to recompile these, we
733                    emulate the SVr4 behavior.  Sigh.  */
734                 /* N.B. Shouldn't the size here be PAGE_SIZE?? */
735                 down(&current->mm->mmap_sem);
736                 error = do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC,
737                                 MAP_FIXED | MAP_PRIVATE, 0);
738                 up(&current->mm->mmap_sem);
739         }
740 
741 #ifdef ELF_PLAT_INIT
742         /*
743          * The ABI may specify that certain registers be set up in special
744          * ways (on i386 %edx is the address of a DT_FINI function, for
745          * example.  This macro performs whatever initialization to
746          * the regs structure is required.
747          */
748         ELF_PLAT_INIT(regs);
749 #endif
750 
751         start_thread(regs, elf_entry, bprm->p);
752         if (current->ptrace & PT_PTRACED)
753                 send_sig(SIGTRAP, current, 0);
754         retval = 0;
755 out:
756         return retval;
757 
758         /* error cleanup */
759 out_free_dentry:
760         allow_write_access(interpreter);
761         fput(interpreter);
762 out_free_interp:
763         if (elf_interpreter)
764                 kfree(elf_interpreter);
765 out_free_file:
766         sys_close(elf_exec_fileno);
767 out_free_ph:
768         kfree(elf_phdata);
769         goto out;
770 }
771 
772 /* This is really simpleminded and specialized - we are loading an
773    a.out library that is given an ELF header. */
774 
775 static int load_elf_library(struct file *file)
776 {
777         struct elf_phdr *elf_phdata;
778         unsigned long elf_bss = 0, bss, len, k;
779         int retval, error, i, j;
780         struct elfhdr elf_ex;
781 
782         error = -ENOEXEC;
783         retval = kernel_read(file, 0, (char *) &elf_ex, sizeof(elf_ex));
784         if (retval != sizeof(elf_ex))
785                 goto out;
786 
787         if (memcmp(elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
788                 goto out;
789 
790         /* First of all, some simple consistency checks */
791         if (elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
792            !elf_check_arch(&elf_ex) || !file->f_op || !file->f_op->mmap)
793                 goto out;
794 
795         /* Now read in all of the header information */
796 
797         j = sizeof(struct elf_phdr) * elf_ex.e_phnum;
798         if (j > ELF_MIN_ALIGN)
799                 goto out;
800 
801         error = -ENOMEM;
802         elf_phdata = (struct elf_phdr *) kmalloc(j, GFP_KERNEL);
803         if (!elf_phdata)
804                 goto out;
805 
806         /* N.B. check for error return?? */
807         retval = kernel_read(file, elf_ex.e_phoff, (char *) elf_phdata,
808                            sizeof(struct elf_phdr) * elf_ex.e_phnum);
809 
810         error = -ENOEXEC;
811         for (j = 0, i = 0; i<elf_ex.e_phnum; i++)
812                 if ((elf_phdata + i)->p_type == PT_LOAD) j++;
813         if (j != 1)
814                 goto out_free_ph;
815 
816         while (elf_phdata->p_type != PT_LOAD) elf_phdata++;
817 
818         /* Now use mmap to map the library into memory. */
819         down(&current->mm->mmap_sem);
820         error = do_mmap(file,
821                         ELF_PAGESTART(elf_phdata->p_vaddr),
822                         (elf_phdata->p_filesz +
823                          ELF_PAGEOFFSET(elf_phdata->p_vaddr)),
824                         PROT_READ | PROT_WRITE | PROT_EXEC,
825                         MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
826                         (elf_phdata->p_offset -
827                          ELF_PAGEOFFSET(elf_phdata->p_vaddr)));
828         up(&current->mm->mmap_sem);
829         if (error != ELF_PAGESTART(elf_phdata->p_vaddr))
830                 goto out_free_ph;
831 
832         k = elf_phdata->p_vaddr + elf_phdata->p_filesz;
833         if (k > elf_bss)
834                 elf_bss = k;
835         padzero(elf_bss);
836 
837         len = ELF_PAGESTART(elf_phdata->p_filesz + elf_phdata->p_vaddr + ELF_MIN_ALIGN - 1);
838         bss = elf_phdata->p_memsz + elf_phdata->p_vaddr;
839         if (bss > len)
840                 do_brk(len, bss - len);
841         error = 0;
842 
843 out_free_ph:
844         kfree(elf_phdata);
845 out:
846         return error;
847 }
848 
849 /*
850  * Note that some platforms still use traditional core dumps and not
851  * the ELF core dump.  Each platform can select it as appropriate.
852  */
853 #ifdef USE_ELF_CORE_DUMP
854 
855 /*
856  * ELF core dumper
857  *
858  * Modelled on fs/exec.c:aout_core_dump()
859  * Jeremy Fitzhardinge <jeremy@sw.oz.au>
860  */
861 /*
862  * These are the only things you should do on a core-file: use only these
863  * functions to write out all the necessary info.
864  */
865 static int dump_write(struct file *file, const void *addr, int nr)
866 {
867         return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
868 }
869 
870 static int dump_seek(struct file *file, off_t off)
871 {
872         if (file->f_op->llseek) {
873                 if (file->f_op->llseek(file, off, 0) != off)
874                         return 0;
875         } else
876                 file->f_pos = off;
877         return 1;
878 }
879 
880 /*
881  * Decide whether a segment is worth dumping; default is yes to be
882  * sure (missing info is worse than too much; etc).
883  * Personally I'd include everything, and use the coredump limit...
884  *
885  * I think we should skip something. But I am not sure how. H.J.
886  */
887 static inline int maydump(struct vm_area_struct *vma)
888 {
889         if (!(vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)))
890                 return 0;
891 
892         /* Do not dump I/O mapped devices! -DaveM */
893         if(vma->vm_flags & VM_IO)
894                 return 0;
895 #if 1
896         if (vma->vm_flags & (VM_WRITE|VM_GROWSUP|VM_GROWSDOWN))
897                 return 1;
898         if (vma->vm_flags & (VM_READ|VM_EXEC|VM_EXECUTABLE|VM_SHARED))
899                 return 0;
900 #endif
901         return 1;
902 }
903 
904 #define roundup(x, y)  ((((x)+((y)-1))/(y))*(y))
905 
906 /* An ELF note in memory */
907 struct memelfnote
908 {
909         const char *name;
910         int type;
911         unsigned int datasz;
912         void *data;
913 };
914 
915 static int notesize(struct memelfnote *en)
916 {
917         int sz;
918 
919         sz = sizeof(struct elf_note);
920         sz += roundup(strlen(en->name), 4);
921         sz += roundup(en->datasz, 4);
922 
923         return sz;
924 }
925 
926 /* #define DEBUG */
927 
928 #ifdef DEBUG
929 static void dump_regs(const char *str, elf_greg_t *r)
930 {
931         int i;
932         static const char *regs[] = { "ebx", "ecx", "edx", "esi", "edi", "ebp",
933                                               "eax", "ds", "es", "fs", "gs",
934                                               "orig_eax", "eip", "cs",
935                                               "efl", "uesp", "ss"};
936         printk("Registers: %s\n", str);
937 
938         for(i = 0; i < ELF_NGREG; i++)
939         {
940                 unsigned long val = r[i];
941                 printk("   %-2d %-5s=%08lx %lu\n", i, regs[i], val, val);
942         }
943 }
944 #endif
945 
946 #define DUMP_WRITE(addr, nr)    \
947         do { if (!dump_write(file, (addr), (nr))) return 0; } while(0)
948 #define DUMP_SEEK(off)  \
949         do { if (!dump_seek(file, (off))) return 0; } while(0)
950 
951 static int writenote(struct memelfnote *men, struct file *file)
952 {
953         struct elf_note en;
954 
955         en.n_namesz = strlen(men->name);
956         en.n_descsz = men->datasz;
957         en.n_type = men->type;
958 
959         DUMP_WRITE(&en, sizeof(en));
960         DUMP_WRITE(men->name, en.n_namesz);
961         /* XXX - cast from long long to long to avoid need for libgcc.a */
962         DUMP_SEEK(roundup((unsigned long)file->f_pos, 4));      /* XXX */
963         DUMP_WRITE(men->data, men->datasz);
964         DUMP_SEEK(roundup((unsigned long)file->f_pos, 4));      /* XXX */
965 
966         return 1;
967 }
968 #undef DUMP_WRITE
969 #undef DUMP_SEEK
970 
971 #define DUMP_WRITE(addr, nr)    \
972         if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
973                 goto end_coredump;
974 #define DUMP_SEEK(off)  \
975         if (!dump_seek(file, (off))) \
976                 goto end_coredump;
977 /*
978  * Actual dumper
979  *
980  * This is a two-pass process; first we find the offsets of the bits,
981  * and then they are actually written out.  If we run out of core limit
982  * we just truncate.
983  */
984 static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file)
985 {
986         int has_dumped = 0;
987         mm_segment_t fs;
988         int segs;
989         size_t size = 0;
990         int i;
991         struct vm_area_struct *vma;
992         struct elfhdr elf;
993         off_t offset = 0, dataoff;
994         unsigned long limit = current->rlim[RLIMIT_CORE].rlim_cur;
995         int numnote = 4;
996         struct memelfnote notes[4];
997         struct elf_prstatus prstatus;   /* NT_PRSTATUS */
998         elf_fpregset_t fpu;             /* NT_PRFPREG */
999         struct elf_prpsinfo psinfo;     /* NT_PRPSINFO */
1000 
1001         segs = current->mm->map_count;
1002 
1003 #ifdef DEBUG
1004         printk("elf_core_dump: %d segs %lu limit\n", segs, limit);
1005 #endif
1006 
1007         /* Set up header */
1008         memcpy(elf.e_ident, ELFMAG, SELFMAG);
1009         elf.e_ident[EI_CLASS] = ELF_CLASS;
1010         elf.e_ident[EI_DATA] = ELF_DATA;
1011         elf.e_ident[EI_VERSION] = EV_CURRENT;
1012         memset(elf.e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);
1013 
1014         elf.e_type = ET_CORE;
1015         elf.e_machine = ELF_ARCH;
1016         elf.e_version = EV_CURRENT;
1017         elf.e_entry = 0;
1018         elf.e_phoff = sizeof(elf);
1019         elf.e_shoff = 0;
1020         elf.e_flags = 0;
1021         elf.e_ehsize = sizeof(elf);
1022         elf.e_phentsize = sizeof(struct elf_phdr);
1023         elf.e_phnum = segs+1;           /* Include notes */
1024         elf.e_shentsize = 0;
1025         elf.e_shnum = 0;
1026         elf.e_shstrndx = 0;
1027 
1028         fs = get_fs();
1029         set_fs(KERNEL_DS);
1030 
1031         has_dumped = 1;
1032         current->flags |= PF_DUMPCORE;
1033 
1034         DUMP_WRITE(&elf, sizeof(elf));
1035         offset += sizeof(elf);                          /* Elf header */
1036         offset += (segs+1) * sizeof(struct elf_phdr);   /* Program headers */
1037 
1038         /*
1039          * Set up the notes in similar form to SVR4 core dumps made
1040          * with info from their /proc.
1041          */
1042         memset(&psinfo, 0, sizeof(psinfo));
1043         memset(&prstatus, 0, sizeof(prstatus));
1044 
1045         notes[0].name = "CORE";
1046         notes[0].type = NT_PRSTATUS;
1047         notes[0].datasz = sizeof(prstatus);
1048         notes[0].data = &prstatus;
1049         prstatus.pr_info.si_signo = prstatus.pr_cursig = signr;
1050         prstatus.pr_sigpend = current->pending.signal.sig[0];
1051         prstatus.pr_sighold = current->blocked.sig[0];
1052         psinfo.pr_pid = prstatus.pr_pid = current->pid;
1053         psinfo.pr_ppid = prstatus.pr_ppid = current->p_pptr->pid;
1054         psinfo.pr_pgrp = prstatus.pr_pgrp = current->pgrp;
1055         psinfo.pr_sid = prstatus.pr_sid = current->session;
1056         prstatus.pr_utime.tv_sec = CT_TO_SECS(current->times.tms_utime);
1057         prstatus.pr_utime.tv_usec = CT_TO_USECS(current->times.tms_utime);
1058         prstatus.pr_stime.tv_sec = CT_TO_SECS(current->times.tms_stime);
1059         prstatus.pr_stime.tv_usec = CT_TO_USECS(current->times.tms_stime);
1060         prstatus.pr_cutime.tv_sec = CT_TO_SECS(current->times.tms_cutime);
1061         prstatus.pr_cutime.tv_usec = CT_TO_USECS(current->times.tms_cutime);
1062         prstatus.pr_cstime.tv_sec = CT_TO_SECS(current->times.tms_cstime);
1063         prstatus.pr_cstime.tv_usec = CT_TO_USECS(current->times.tms_cstime);
1064 
1065         /*
1066          * This transfers the registers from regs into the standard
1067          * coredump arrangement, whatever that is.
1068          */
1069 #ifdef ELF_CORE_COPY_REGS
1070         ELF_CORE_COPY_REGS(prstatus.pr_reg, regs)
1071 #else
1072         if (sizeof(elf_gregset_t) != sizeof(struct pt_regs))
1073         {
1074                 printk("sizeof(elf_gregset_t) (%ld) != sizeof(struct pt_regs) (%ld)\n",
1075                         (long)sizeof(elf_gregset_t), (long)sizeof(struct pt_regs));
1076         }
1077         else
1078                 *(struct pt_regs *)&prstatus.pr_reg = *regs;
1079 #endif
1080 
1081 #ifdef DEBUG
1082         dump_regs("Passed in regs", (elf_greg_t *)regs);
1083         dump_regs("prstatus regs", (elf_greg_t *)&prstatus.pr_reg);
1084 #endif
1085 
1086         notes[1].name = "CORE";
1087         notes[1].type = NT_PRPSINFO;
1088         notes[1].datasz = sizeof(psinfo);
1089         notes[1].data = &psinfo;
1090         i = current->state ? ffz(~current->state) + 1 : 0;
1091         psinfo.pr_state = i;
1092         psinfo.pr_sname = (i < 0 || i > 5) ? '.' : "RSDZTD"[i];
1093         psinfo.pr_zomb = psinfo.pr_sname == 'Z';
1094         psinfo.pr_nice = current->nice;
1095         psinfo.pr_flag = current->flags;
1096         psinfo.pr_uid = NEW_TO_OLD_UID(current->uid);
1097         psinfo.pr_gid = NEW_TO_OLD_GID(current->gid);
1098         {
1099                 int i, len;
1100 
1101                 set_fs(fs);
1102 
1103                 len = current->mm->arg_end - current->mm->arg_start;
1104                 if (len >= ELF_PRARGSZ)
1105                         len = ELF_PRARGSZ-1;
1106                 copy_from_user(&psinfo.pr_psargs,
1107                               (const char *)current->mm->arg_start, len);
1108                 for(i = 0; i < len; i++)
1109                         if (psinfo.pr_psargs[i] == 0)
1110                                 psinfo.pr_psargs[i] = ' ';
1111                 psinfo.pr_psargs[len] = 0;
1112 
1113                 set_fs(KERNEL_DS);
1114         }
1115         strncpy(psinfo.pr_fname, current->comm, sizeof(psinfo.pr_fname));
1116 
1117         notes[2].name = "CORE";
1118         notes[2].type = NT_TASKSTRUCT;
1119         notes[2].datasz = sizeof(*current);
1120         notes[2].data = current;
1121 
1122         /* Try to dump the FPU. */
1123         prstatus.pr_fpvalid = dump_fpu (regs, &fpu);
1124         if (!prstatus.pr_fpvalid)
1125         {
1126                 numnote--;
1127         }
1128         else
1129         {
1130                 notes[3].name = "CORE";
1131                 notes[3].type = NT_PRFPREG;
1132                 notes[3].datasz = sizeof(fpu);
1133                 notes[3].data = &fpu;
1134         }
1135         
1136         /* Write notes phdr entry */
1137         {
1138                 struct elf_phdr phdr;
1139                 int sz = 0;
1140 
1141                 for(i = 0; i < numnote; i++)
1142                         sz += notesize(&notes[i]);
1143 
1144                 phdr.p_type = PT_NOTE;
1145                 phdr.p_offset = offset;
1146                 phdr.p_vaddr = 0;
1147                 phdr.p_paddr = 0;
1148                 phdr.p_filesz = sz;
1149                 phdr.p_memsz = 0;
1150                 phdr.p_flags = 0;
1151                 phdr.p_align = 0;
1152 
1153                 offset += phdr.p_filesz;
1154                 DUMP_WRITE(&phdr, sizeof(phdr));
1155         }
1156 
1157         /* Page-align dumped data */
1158         dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
1159 
1160         /* Write program headers for segments dump */
1161         for(vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
1162                 struct elf_phdr phdr;
1163                 size_t sz;
1164 
1165                 sz = vma->vm_end - vma->vm_start;
1166 
1167                 phdr.p_type = PT_LOAD;
1168                 phdr.p_offset = offset;
1169                 phdr.p_vaddr = vma->vm_start;
1170                 phdr.p_paddr = 0;
1171                 phdr.p_filesz = maydump(vma) ? sz : 0;
1172                 phdr.p_memsz = sz;
1173                 offset += phdr.p_filesz;
1174                 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
1175                 if (vma->vm_flags & VM_WRITE) phdr.p_flags |= PF_W;
1176                 if (vma->vm_flags & VM_EXEC) phdr.p_flags |= PF_X;
1177                 phdr.p_align = ELF_EXEC_PAGESIZE;
1178 
1179                 DUMP_WRITE(&phdr, sizeof(phdr));
1180         }
1181 
1182         for(i = 0; i < numnote; i++)
1183                 if (!writenote(&notes[i], file))
1184                         goto end_coredump;
1185 
1186         set_fs(fs);
1187 
1188         DUMP_SEEK(dataoff);
1189 
1190         for(vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
1191                 unsigned long addr;
1192 
1193                 if (!maydump(vma))
1194                         continue;
1195 #ifdef DEBUG
1196                 printk("elf_core_dump: writing %08lx %lx\n", addr, len);
1197 #endif
1198                 for (addr = vma->vm_start;
1199                      addr < vma->vm_end;
1200                      addr += PAGE_SIZE) {
1201                         pgd_t *pgd;
1202                         pmd_t *pmd;
1203                         pte_t *pte;
1204 
1205                         pgd = pgd_offset(vma->vm_mm, addr);
1206                         pmd = pmd_alloc(pgd, addr);
1207         
1208                         if (!pmd)
1209                                 goto end_coredump;
1210                         pte = pte_alloc(pmd, addr);
1211                         if (!pte)
1212                                 goto end_coredump;
1213                         if (!pte_present(*pte) &&
1214                             pte_none(*pte)) {
1215                                 DUMP_SEEK (file->f_pos + PAGE_SIZE);
1216                         } else {
1217                                 DUMP_WRITE((void*)addr, PAGE_SIZE);
1218                         }
1219                 }
1220         }
1221 
1222         if ((off_t) file->f_pos != offset) {
1223                 /* Sanity check */
1224                 printk("elf_core_dump: file->f_pos (%ld) != offset (%ld)\n",
1225                        (off_t) file->f_pos, offset);
1226         }
1227 
1228  end_coredump:
1229         set_fs(fs);
1230         return has_dumped;
1231 }
1232 #endif          /* USE_ELF_CORE_DUMP */
1233 
1234 static int __init init_elf_binfmt(void)
1235 {
1236         return register_binfmt(&elf_format);
1237 }
1238 
1239 static void __exit exit_elf_binfmt(void)
1240 {
1241         /* Remove the COFF and ELF loaders. */
1242         unregister_binfmt(&elf_format);
1243 }
1244 
1245 module_init(init_elf_binfmt)
1246 module_exit(exit_elf_binfmt)
1247 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.