1 /* This is the Linux kernel elf-loading code, ported into user space */
15 #include "linux_bin.h"
19 /* Necessary parameters */
20 #define ALPHA_PAGE_SIZE 4096
21 #define X86_PAGE_SIZE 4096
23 #define ALPHA_PAGE_MASK (~(ALPHA_PAGE_SIZE-1))
24 #define X86_PAGE_MASK (~(X86_PAGE_SIZE-1))
26 #define ALPHA_PAGE_ALIGN(addr) ((((addr)+ALPHA_PAGE_SIZE)-1)&ALPHA_PAGE_MASK)
27 #define X86_PAGE_ALIGN(addr) ((((addr)+X86_PAGE_SIZE)-1)&X86_PAGE_MASK)
31 #define X86_ELF_EXEC_PAGESIZE X86_PAGE_SIZE
32 #define X86_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(X86_ELF_EXEC_PAGESIZE-1))
33 #define X86_ELF_PAGEOFFSET(_v) ((_v) & (X86_ELF_EXEC_PAGESIZE-1))
35 #define ALPHA_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(ALPHA_PAGE_SIZE-1))
36 #define ALPHA_ELF_PAGEOFFSET(_v) ((_v) & (ALPHA_PAGE_SIZE-1))
38 #define INTERPRETER_NONE 0
39 #define INTERPRETER_AOUT 1
40 #define INTERPRETER_ELF 2
42 #define DLINFO_ITEMS 12
44 /* Where we find X86 libraries... */
45 //#define X86_DEFAULT_LIB_DIR "/usr/x86/"
46 #define X86_DEFAULT_LIB_DIR "/"
48 //extern void * mmap4k();
49 #define mmap4k(a, b, c, d, e, f) mmap((void *)(a), b, c, d, e, f)
51 extern unsigned long x86_stack_size;
53 static int load_aout_interp(void * exptr, int interp_fd);
56 static void bswap_ehdr(Elf32_Ehdr *ehdr)
58 bswap16s(&ehdr->e_type); /* Object file type */
59 bswap16s(&ehdr->e_machine); /* Architecture */
60 bswap32s(&ehdr->e_version); /* Object file version */
61 bswap32s(&ehdr->e_entry); /* Entry point virtual address */
62 bswap32s(&ehdr->e_phoff); /* Program header table file offset */
63 bswap32s(&ehdr->e_shoff); /* Section header table file offset */
64 bswap32s(&ehdr->e_flags); /* Processor-specific flags */
65 bswap16s(&ehdr->e_ehsize); /* ELF header size in bytes */
66 bswap16s(&ehdr->e_phentsize); /* Program header table entry size */
67 bswap16s(&ehdr->e_phnum); /* Program header table entry count */
68 bswap16s(&ehdr->e_shentsize); /* Section header table entry size */
69 bswap16s(&ehdr->e_shnum); /* Section header table entry count */
70 bswap16s(&ehdr->e_shstrndx); /* Section header string table index */
73 static void bswap_phdr(Elf32_Phdr *phdr)
75 bswap32s(&phdr->p_type); /* Segment type */
76 bswap32s(&phdr->p_offset); /* Segment file offset */
77 bswap32s(&phdr->p_vaddr); /* Segment virtual address */
78 bswap32s(&phdr->p_paddr); /* Segment physical address */
79 bswap32s(&phdr->p_filesz); /* Segment size in file */
80 bswap32s(&phdr->p_memsz); /* Segment size in memory */
81 bswap32s(&phdr->p_flags); /* Segment flags */
82 bswap32s(&phdr->p_align); /* Segment alignment */
86 static void * get_free_page(void)
90 /* User-space version of kernel get_free_page. Returns a page-aligned
91 * page-sized chunk of memory.
93 retval = mmap4k(0, ALPHA_PAGE_SIZE, PROT_READ|PROT_WRITE,
94 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
96 if((long)retval == -1) {
97 perror("get_free_page");
105 static void free_page(void * pageaddr)
107 (void)munmap(pageaddr, ALPHA_PAGE_SIZE);
111 * 'copy_string()' copies argument/envelope strings from user
112 * memory to free pages in kernel mem. These are in a format ready
113 * to be put directly into the top of new user memory.
116 static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
119 char *tmp, *tmp1, *pag = NULL;
123 return 0; /* bullet-proofing */
126 if (!(tmp1 = tmp = get_user(argv+argc))) {
127 fprintf(stderr, "VFS: argc is wrong");
130 while (get_user(tmp++));
132 if (p < len) { /* this shouldn't happen - 128kB */
138 offset = p % X86_PAGE_SIZE;
139 if (!(pag = (char *) page[p/X86_PAGE_SIZE]) &&
140 !(pag = (char *) page[p/X86_PAGE_SIZE] =
141 (unsigned long *) get_free_page())) {
145 if (len == 0 || offset == 0) {
146 *(pag + offset) = get_user(tmp);
149 int bytes_to_copy = (len > offset) ? offset : len;
150 tmp -= bytes_to_copy;
152 offset -= bytes_to_copy;
153 len -= bytes_to_copy;
154 memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);
161 static int in_group_p(gid_t g)
163 /* return TRUE if we're in the specified group, FALSE otherwise */
166 gid_t grouplist[NGROUPS];
168 ngroup = getgroups(NGROUPS, grouplist);
169 for(i = 0; i < ngroup; i++) {
170 if(grouplist[i] == g) {
177 static int count(char ** vec)
181 for(i = 0; *vec; i++) {
188 static int prepare_binprm(struct linux_binprm *bprm)
192 int retval, id_change;
194 if(fstat(bprm->fd, &st) < 0) {
199 if(!S_ISREG(mode)) { /* Must be regular file */
202 if(!(mode & 0111)) { /* Must have at least one execute bit set */
206 bprm->e_uid = geteuid();
207 bprm->e_gid = getegid();
212 bprm->e_uid = st.st_uid;
213 if(bprm->e_uid != geteuid()) {
220 * If setgid is set but no group execute bit then this
221 * is a candidate for mandatory locking, not a setgid
224 if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
225 bprm->e_gid = st.st_gid;
226 if (!in_group_p(bprm->e_gid)) {
231 memset(bprm->buf, 0, sizeof(bprm->buf));
232 retval = lseek(bprm->fd, 0L, SEEK_SET);
234 retval = read(bprm->fd, bprm->buf, 128);
237 perror("prepare_binprm");
239 /* return(-errno); */
246 unsigned long setup_arg_pages(unsigned long p, struct linux_binprm * bprm,
247 struct image_info * info)
249 unsigned long stack_base;
251 extern unsigned long stktop;
253 stack_base = X86_STACK_TOP - MAX_ARG_PAGES*X86_PAGE_SIZE;
257 bprm->loader += stack_base;
259 bprm->exec += stack_base;
261 /* Create enough stack to hold everything. If we don't use
262 * it for args, we'll use it for something else...
264 if(x86_stack_size > MAX_ARG_PAGES*X86_PAGE_SIZE) {
265 if((long)mmap4k((void *)(X86_STACK_TOP-x86_stack_size), x86_stack_size + X86_PAGE_SIZE,
266 PROT_READ | PROT_WRITE,
267 MAP_GROWSDOWN | MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) == -1) {
273 if((long)mmap4k((void *)stack_base, (MAX_ARG_PAGES+1)*X86_PAGE_SIZE,
274 PROT_READ | PROT_WRITE,
275 MAP_GROWSDOWN | MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) == -1) {
283 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
287 memcpy((void *)stack_base, (void *)bprm->page[i], X86_PAGE_SIZE);
288 free_page((void *)bprm->page[i]);
290 stack_base += X86_PAGE_SIZE;
295 static void set_brk(unsigned long start, unsigned long end)
297 /* page-align the start and end addresses... */
298 start = ALPHA_PAGE_ALIGN(start);
299 end = ALPHA_PAGE_ALIGN(end);
302 if((long)mmap4k(start, end - start,
303 PROT_READ | PROT_WRITE | PROT_EXEC,
304 MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) == -1) {
305 perror("cannot mmap brk");
311 /* We need to explicitly zero any fractional pages
312 after the data section (i.e. bss). This would
313 contain the junk from the file that should not
317 static void padzero(unsigned long elf_bss)
322 nbyte = elf_bss & (ALPHA_PAGE_SIZE-1); /* was X86_PAGE_SIZE - JRP */
324 nbyte = ALPHA_PAGE_SIZE - nbyte;
325 fpnt = (char *) elf_bss;
332 static unsigned int * create_elf_tables(char *p, int argc, int envc,
333 struct elfhdr * exec,
334 unsigned long load_addr,
335 unsigned long interp_load_addr, int ibcs,
336 struct image_info *info)
338 unsigned int *argv, *envp, *dlinfo;
343 * Force 16 byte alignment here for generality.
345 sp = (unsigned int *) (~15UL & (unsigned long) p);
346 sp -= exec ? DLINFO_ITEMS*2 : 2;
356 alpha_envp = (char **)malloc((envc+1) * sizeof(char *));
358 #define NEW_AUX_ENT(id, val) \
359 put_user ((id), dlinfo++); \
360 put_user ((val), dlinfo++)
362 if (exec) { /* Put this here for an ELF program interpreter */
363 struct elf_phdr * eppnt;
364 eppnt = (struct elf_phdr *)((unsigned long)exec->e_phoff);
366 NEW_AUX_ENT (AT_PHDR, (unsigned int)(load_addr + exec->e_phoff));
367 NEW_AUX_ENT (AT_PHENT, (unsigned int)(sizeof (struct elf_phdr)));
368 NEW_AUX_ENT (AT_PHNUM, (unsigned int)(exec->e_phnum));
369 NEW_AUX_ENT (AT_PAGESZ, (unsigned int)(ALPHA_PAGE_SIZE));
370 NEW_AUX_ENT (AT_BASE, (unsigned int)(interp_load_addr));
371 NEW_AUX_ENT (AT_FLAGS, (unsigned int)0);
372 NEW_AUX_ENT (AT_ENTRY, (unsigned int) exec->e_entry);
373 NEW_AUX_ENT (AT_UID, (unsigned int) getuid());
374 NEW_AUX_ENT (AT_EUID, (unsigned int) geteuid());
375 NEW_AUX_ENT (AT_GID, (unsigned int) getgid());
376 NEW_AUX_ENT (AT_EGID, (unsigned int) getegid());
378 NEW_AUX_ENT (AT_NULL, 0);
380 put_user((unsigned int)argc,--sp);
381 info->arg_start = (unsigned int)((unsigned long)p & 0xffffffff);
384 while (get_user(p++)) /* nothing */ ;
387 info->arg_end = info->env_start = (unsigned int)((unsigned long)p & 0xffffffff);
388 __environ = alpha_envp;
390 *alpha_envp++ = (char *)p;
392 while (get_user(p++)) /* nothing */ ;
396 info->env_end = (unsigned int)((unsigned long)p & 0xffffffff);
402 static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
404 unsigned long *interp_load_addr)
406 struct elf_phdr *elf_phdata = NULL;
407 struct elf_phdr *eppnt;
408 unsigned long load_addr;
409 int load_addr_set = 0;
411 unsigned long last_bss, elf_bss;
419 /* We put this here so that mmap will search for the *first*
420 * available memory...
422 load_addr = INTERP_LOADADDR;
424 /* First of all, some simple consistency checks */
425 if ((interp_elf_ex->e_type != ET_EXEC &&
426 interp_elf_ex->e_type != ET_DYN) ||
427 !elf_check_arch(interp_elf_ex->e_machine)) {
431 /* Now read in all of the header information */
433 if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > X86_PAGE_SIZE)
436 elf_phdata = (struct elf_phdr *)
437 malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
443 * If the size of this structure has changed, then punt, since
444 * we will be doing the wrong thing.
446 if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr))
452 retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET);
454 retval = read(interpreter_fd,
456 sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
460 perror("load_elf_interp");
467 for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
472 for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++)
473 if (eppnt->p_type == PT_LOAD) {
474 int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
476 unsigned long vaddr = 0;
479 if (eppnt->p_flags & PF_R) elf_prot = PROT_READ;
480 if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
481 if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
482 if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) {
483 elf_type |= MAP_FIXED;
484 vaddr = eppnt->p_vaddr;
486 error = (unsigned long)mmap4k(load_addr+X86_ELF_PAGESTART(vaddr),
487 eppnt->p_filesz + X86_ELF_PAGEOFFSET(eppnt->p_vaddr),
491 eppnt->p_offset - X86_ELF_PAGEOFFSET(eppnt->p_vaddr));
493 if (error > -1024UL) {
495 close(interpreter_fd);
500 if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
506 * Find the end of the file mapping for this phdr, and keep
507 * track of the largest address we see for this.
509 k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
510 if (k > elf_bss) elf_bss = k;
513 * Do the same thing for the memory mapping - between
514 * elf_bss and last_bss is the bss section.
516 k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
517 if (k > last_bss) last_bss = k;
520 /* Now use mmap to map the library into memory. */
522 close(interpreter_fd);
525 * Now fill out the bss section. First pad the last page up
526 * to the page boundary, and then perform a mmap to make sure
527 * that there are zeromapped pages up to and including the last
531 elf_bss = X86_ELF_PAGESTART(elf_bss + ALPHA_PAGE_SIZE - 1); /* What we have mapped so far */
533 /* Map the last of the bss segment */
534 if (last_bss > elf_bss) {
535 mmap4k(elf_bss, last_bss-elf_bss,
536 PROT_READ|PROT_WRITE|PROT_EXEC,
537 MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
541 *interp_load_addr = load_addr;
542 return ((unsigned long) interp_elf_ex->e_entry) + load_addr;
547 static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs,
548 struct image_info * info)
550 struct elfhdr elf_ex;
551 struct elfhdr interp_elf_ex;
552 struct exec interp_ex;
553 int interpreter_fd = -1; /* avoid warning */
554 unsigned long load_addr;
555 int load_addr_set = 0;
556 unsigned int interpreter_type = INTERPRETER_NONE;
557 unsigned char ibcs2_interpreter;
560 struct elf_phdr * elf_ppnt;
561 struct elf_phdr *elf_phdata;
562 unsigned long elf_bss, k, elf_brk;
564 char * elf_interpreter;
565 unsigned long elf_entry, interp_load_addr = 0;
567 unsigned long start_code, end_code, end_data;
568 unsigned long elf_stack;
569 char passed_fileno[6];
571 ibcs2_interpreter = 0;
574 elf_ex = *((struct elfhdr *) bprm->buf); /* exec-header */
579 if (elf_ex.e_ident[0] != 0x7f ||
580 strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) {
585 /* First of all, some simple consistency checks */
586 if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) ||
587 (! elf_check_arch(elf_ex.e_machine))) {
591 /* Now read in all of the header information */
593 elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize*elf_ex.e_phnum);
594 if (elf_phdata == NULL) {
598 retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET);
600 retval = read(bprm->fd, (char *) elf_phdata,
601 elf_ex.e_phentsize * elf_ex.e_phnum);
605 perror("load_elf_binary");
611 elf_ppnt = elf_phdata;
618 elf_interpreter = NULL;
623 for(i=0;i < elf_ex.e_phnum; i++) {
624 if (elf_ppnt->p_type == PT_INTERP) {
625 if ( elf_interpreter != NULL )
628 free(elf_interpreter);
633 /* This is the program interpreter used for
634 * shared libraries - for now assume that this
635 * is an a.out format binary
638 elf_interpreter = (char *)malloc(elf_ppnt->p_filesz+strlen(X86_DEFAULT_LIB_DIR));
640 if (elf_interpreter == NULL) {
646 strcpy(elf_interpreter, X86_DEFAULT_LIB_DIR);
647 retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET);
649 retval = read(bprm->fd,
650 elf_interpreter+strlen(X86_DEFAULT_LIB_DIR),
654 perror("load_elf_binary2");
658 /* If the program interpreter is one of these two,
659 then assume an iBCS2 image. Otherwise assume
660 a native linux image. */
662 /* JRP - Need to add X86 lib dir stuff here... */
664 if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||
665 strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) {
666 ibcs2_interpreter = 1;
670 printf("Using ELF interpreter %s\n", elf_interpreter);
673 retval = open(elf_interpreter, O_RDONLY);
675 interpreter_fd = retval;
678 perror(elf_interpreter);
680 /* retval = -errno; */
685 retval = lseek(interpreter_fd, 0, SEEK_SET);
687 retval = read(interpreter_fd,bprm->buf,128);
691 interp_ex = *((struct exec *) bprm->buf); /* aout exec-header */
692 interp_elf_ex=*((struct elfhdr *) bprm->buf); /* elf exec-header */
695 perror("load_elf_binary3");
698 free(elf_interpreter);
706 /* Some simple consistency checks for the interpreter */
707 if (elf_interpreter){
708 interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
710 /* Now figure out which format our binary is */
711 if ((N_MAGIC(interp_ex) != OMAGIC) && (N_MAGIC(interp_ex) != ZMAGIC) &&
712 (N_MAGIC(interp_ex) != QMAGIC)) {
713 interpreter_type = INTERPRETER_ELF;
716 if (interp_elf_ex.e_ident[0] != 0x7f ||
717 strncmp(&interp_elf_ex.e_ident[1], "ELF",3) != 0) {
718 interpreter_type &= ~INTERPRETER_ELF;
721 if (!interpreter_type) {
722 free(elf_interpreter);
729 /* OK, we are done with that, now set up the arg stuff,
730 and then start this sucker up */
732 if (!bprm->sh_bang) {
735 if (interpreter_type == INTERPRETER_AOUT) {
736 sprintf(passed_fileno, "%d", bprm->fd);
737 passed_p = passed_fileno;
739 if (elf_interpreter) {
740 bprm->p = copy_strings(1,&passed_p,bprm->page,bprm->p);
745 if (elf_interpreter) {
746 free(elf_interpreter);
754 /* OK, This is the point of no return */
757 info->start_mmap = (unsigned long)ELF_START_MMAP;
759 elf_entry = (unsigned long) elf_ex.e_entry;
761 /* Do this so that we can load the interpreter, if need be. We will
762 change some of these later */
764 bprm->p = setup_arg_pages(bprm->p, bprm, info);
765 info->start_stack = bprm->p;
767 /* Now we do a little grungy work by mmaping the ELF image into
768 * the correct location in memory. At this point, we assume that
769 * the image should be loaded at fixed address, not at a variable
775 for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
776 if (elf_ppnt->p_type == PT_LOAD) {
778 if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
779 if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
780 if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
782 mapped_addr = mmap4k(X86_ELF_PAGESTART(elf_ppnt->p_vaddr),
783 (elf_ppnt->p_filesz +
784 X86_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),
786 (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
788 (elf_ppnt->p_offset -
789 X86_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));
791 if((unsigned long)mapped_addr == 0xffffffffffffffff) {
799 if (X86_ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack)
800 elf_stack = X86_ELF_PAGESTART(elf_ppnt->p_vaddr);
803 if (!load_addr_set) {
804 load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;
807 k = elf_ppnt->p_vaddr;
808 if (k < start_code) start_code = k;
809 k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
810 if (k > elf_bss) elf_bss = k;
812 if ((elf_ppnt->p_flags & PF_X) && end_code < k)
814 if ( !(elf_ppnt->p_flags & PF_W) && end_code < k)
817 if (end_data < k) end_data = k;
818 k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
819 if (k > elf_brk) elf_brk = k;
823 if (elf_interpreter) {
824 if (interpreter_type & 1) {
825 elf_entry = load_aout_interp(&interp_ex, interpreter_fd);
827 else if (interpreter_type & 2) {
828 elf_entry = load_elf_interp(&interp_elf_ex, interpreter_fd,
832 close(interpreter_fd);
833 free(elf_interpreter);
835 if (elf_entry == ~0UL) {
836 printf("Unable to load interpreter\n");
845 if (interpreter_type != INTERPRETER_AOUT) close(bprm->fd);
846 info->personality = (ibcs2_interpreter ? PER_SVR4 : PER_LINUX);
849 info->start_stack = bprm->p = elf_stack - 4;
851 bprm->p = (unsigned long)
852 create_elf_tables((char *)bprm->p,
855 (interpreter_type == INTERPRETER_ELF ? &elf_ex : NULL),
858 (interpreter_type == INTERPRETER_AOUT ? 0 : 1),
860 if (interpreter_type == INTERPRETER_AOUT)
861 info->arg_start += strlen(passed_fileno) + 1;
862 info->start_brk = info->brk = elf_brk;
863 info->end_code = end_code;
864 info->start_code = start_code;
865 info->end_data = end_data;
866 info->start_stack = bprm->p;
868 /* Calling set_brk effectively mmaps the pages that we need for the bss and break
870 set_brk(elf_bss, elf_brk);
875 printf("(start_brk) %x\n" , info->start_brk);
876 printf("(end_code) %x\n" , info->end_code);
877 printf("(start_code) %x\n" , info->start_code);
878 printf("(end_data) %x\n" , info->end_data);
879 printf("(start_stack) %x\n" , info->start_stack);
880 printf("(brk) %x\n" , info->brk);
883 if ( info->personality == PER_SVR4 )
885 /* Why this, you ask??? Well SVr4 maps page 0 as read-only,
886 and some applications "depend" upon this behavior.
887 Since we do not have the power to recompile these, we
888 emulate the SVr4 behavior. Sigh. */
889 mapped_addr = mmap4k(NULL, ALPHA_PAGE_SIZE, PROT_READ | PROT_EXEC,
890 MAP_FIXED | MAP_PRIVATE, -1, 0);
895 * The ABI may specify that certain registers be set up in special
896 * ways (on i386 %edx is the address of a DT_FINI function, for
897 * example. This macro performs whatever initialization to
898 * the regs structure is required.
904 info->entry = elf_entry;
911 int elf_exec(const char * filename, char ** argv, char ** envp,
912 struct pt_regs * regs, struct image_info *infop)
914 struct linux_binprm bprm;
918 bprm.p = X86_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int);
919 for (i=0 ; i<MAX_ARG_PAGES ; i++) /* clear page-table */
921 retval = open(filename, O_RDONLY);
930 bprm.filename = (char *)filename;
935 bprm.argc = count(argv);
936 bprm.envc = count(envp);
938 retval = prepare_binprm(&bprm);
941 bprm.p = copy_strings(1, &bprm.filename, bprm.page, bprm.p);
943 bprm.p = copy_strings(bprm.envc,envp,bprm.page,bprm.p);
944 bprm.p = copy_strings(bprm.argc,argv,bprm.page,bprm.p);
951 retval = load_elf_binary(&bprm,regs,infop);
954 /* success. Initialize important registers */
955 regs->esp = infop->start_stack;
956 regs->eip = infop->entry;
960 /* Something went wrong, return the inode and free the argument pages*/
961 for (i=0 ; i<MAX_ARG_PAGES ; i++) {
962 free_page((void *)bprm.page[i]);
968 static int load_aout_interp(void * exptr, int interp_fd)
970 printf("a.out interpreter not yet supported\n");