]>
git.proxmox.com Git - qemu.git/blob - linux-user/elfload.c
43d989e9a08edd959727a8026abad485d97dc667
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 target_ulong
*argv
, *envp
, *dlinfo
;
342 * Force 16 byte alignment here for generality.
344 sp
= (unsigned int *) (~15UL & (unsigned long) p
);
345 sp
-= exec
? DLINFO_ITEMS
*2 : 2;
352 put_user(tswapl((target_ulong
)envp
),--sp
);
353 put_user(tswapl((target_ulong
)argv
),--sp
);
356 #define NEW_AUX_ENT(id, val) \
357 put_user (tswapl(id), dlinfo++); \
358 put_user (tswapl(val), dlinfo++)
360 if (exec
) { /* Put this here for an ELF program interpreter */
361 struct elf_phdr
* eppnt
;
362 eppnt
= (struct elf_phdr
*)((unsigned long)exec
->e_phoff
);
364 NEW_AUX_ENT (AT_PHDR
, (unsigned int)(load_addr
+ exec
->e_phoff
));
365 NEW_AUX_ENT (AT_PHENT
, (unsigned int)(sizeof (struct elf_phdr
)));
366 NEW_AUX_ENT (AT_PHNUM
, (unsigned int)(exec
->e_phnum
));
367 NEW_AUX_ENT (AT_PAGESZ
, (unsigned int)(ALPHA_PAGE_SIZE
));
368 NEW_AUX_ENT (AT_BASE
, (unsigned int)(interp_load_addr
));
369 NEW_AUX_ENT (AT_FLAGS
, (unsigned int)0);
370 NEW_AUX_ENT (AT_ENTRY
, (unsigned int) exec
->e_entry
);
371 NEW_AUX_ENT (AT_UID
, (unsigned int) getuid());
372 NEW_AUX_ENT (AT_EUID
, (unsigned int) geteuid());
373 NEW_AUX_ENT (AT_GID
, (unsigned int) getgid());
374 NEW_AUX_ENT (AT_EGID
, (unsigned int) getegid());
376 NEW_AUX_ENT (AT_NULL
, 0);
378 put_user(tswapl(argc
),--sp
);
379 info
->arg_start
= (unsigned int)((unsigned long)p
& 0xffffffff);
381 put_user(tswapl((target_ulong
)p
),argv
++);
382 while (get_user(p
++)) /* nothing */ ;
385 info
->arg_end
= info
->env_start
= (unsigned int)((unsigned long)p
& 0xffffffff);
387 put_user(tswapl((target_ulong
)p
),envp
++);
388 while (get_user(p
++)) /* nothing */ ;
391 info
->env_end
= (unsigned int)((unsigned long)p
& 0xffffffff);
397 static unsigned long load_elf_interp(struct elfhdr
* interp_elf_ex
,
399 unsigned long *interp_load_addr
)
401 struct elf_phdr
*elf_phdata
= NULL
;
402 struct elf_phdr
*eppnt
;
403 unsigned long load_addr
;
404 int load_addr_set
= 0;
406 unsigned long last_bss
, elf_bss
;
414 /* We put this here so that mmap will search for the *first*
415 * available memory...
417 load_addr
= INTERP_LOADADDR
;
419 /* First of all, some simple consistency checks */
420 if ((interp_elf_ex
->e_type
!= ET_EXEC
&&
421 interp_elf_ex
->e_type
!= ET_DYN
) ||
422 !elf_check_arch(interp_elf_ex
->e_machine
)) {
426 /* Now read in all of the header information */
428 if (sizeof(struct elf_phdr
) * interp_elf_ex
->e_phnum
> X86_PAGE_SIZE
)
431 elf_phdata
= (struct elf_phdr
*)
432 malloc(sizeof(struct elf_phdr
) * interp_elf_ex
->e_phnum
);
438 * If the size of this structure has changed, then punt, since
439 * we will be doing the wrong thing.
441 if (interp_elf_ex
->e_phentsize
!= sizeof(struct elf_phdr
))
447 retval
= lseek(interpreter_fd
, interp_elf_ex
->e_phoff
, SEEK_SET
);
449 retval
= read(interpreter_fd
,
451 sizeof(struct elf_phdr
) * interp_elf_ex
->e_phnum
);
455 perror("load_elf_interp");
462 for (i
=0; i
<interp_elf_ex
->e_phnum
; i
++, eppnt
++) {
467 for(i
=0; i
<interp_elf_ex
->e_phnum
; i
++, eppnt
++)
468 if (eppnt
->p_type
== PT_LOAD
) {
469 int elf_type
= MAP_PRIVATE
| MAP_DENYWRITE
;
471 unsigned long vaddr
= 0;
474 if (eppnt
->p_flags
& PF_R
) elf_prot
= PROT_READ
;
475 if (eppnt
->p_flags
& PF_W
) elf_prot
|= PROT_WRITE
;
476 if (eppnt
->p_flags
& PF_X
) elf_prot
|= PROT_EXEC
;
477 if (interp_elf_ex
->e_type
== ET_EXEC
|| load_addr_set
) {
478 elf_type
|= MAP_FIXED
;
479 vaddr
= eppnt
->p_vaddr
;
481 error
= (unsigned long)mmap4k(load_addr
+X86_ELF_PAGESTART(vaddr
),
482 eppnt
->p_filesz
+ X86_ELF_PAGEOFFSET(eppnt
->p_vaddr
),
486 eppnt
->p_offset
- X86_ELF_PAGEOFFSET(eppnt
->p_vaddr
));
488 if (error
> -1024UL) {
490 close(interpreter_fd
);
495 if (!load_addr_set
&& interp_elf_ex
->e_type
== ET_DYN
) {
501 * Find the end of the file mapping for this phdr, and keep
502 * track of the largest address we see for this.
504 k
= load_addr
+ eppnt
->p_vaddr
+ eppnt
->p_filesz
;
505 if (k
> elf_bss
) elf_bss
= k
;
508 * Do the same thing for the memory mapping - between
509 * elf_bss and last_bss is the bss section.
511 k
= load_addr
+ eppnt
->p_memsz
+ eppnt
->p_vaddr
;
512 if (k
> last_bss
) last_bss
= k
;
515 /* Now use mmap to map the library into memory. */
517 close(interpreter_fd
);
520 * Now fill out the bss section. First pad the last page up
521 * to the page boundary, and then perform a mmap to make sure
522 * that there are zeromapped pages up to and including the last
526 elf_bss
= X86_ELF_PAGESTART(elf_bss
+ ALPHA_PAGE_SIZE
- 1); /* What we have mapped so far */
528 /* Map the last of the bss segment */
529 if (last_bss
> elf_bss
) {
530 mmap4k(elf_bss
, last_bss
-elf_bss
,
531 PROT_READ
|PROT_WRITE
|PROT_EXEC
,
532 MAP_FIXED
|MAP_PRIVATE
|MAP_ANONYMOUS
, -1, 0);
536 *interp_load_addr
= load_addr
;
537 return ((unsigned long) interp_elf_ex
->e_entry
) + load_addr
;
542 static int load_elf_binary(struct linux_binprm
* bprm
, struct target_pt_regs
* regs
,
543 struct image_info
* info
)
545 struct elfhdr elf_ex
;
546 struct elfhdr interp_elf_ex
;
547 struct exec interp_ex
;
548 int interpreter_fd
= -1; /* avoid warning */
549 unsigned long load_addr
;
550 int load_addr_set
= 0;
551 unsigned int interpreter_type
= INTERPRETER_NONE
;
552 unsigned char ibcs2_interpreter
;
555 struct elf_phdr
* elf_ppnt
;
556 struct elf_phdr
*elf_phdata
;
557 unsigned long elf_bss
, k
, elf_brk
;
559 char * elf_interpreter
;
560 unsigned long elf_entry
, interp_load_addr
= 0;
562 unsigned long start_code
, end_code
, end_data
;
563 unsigned long elf_stack
;
564 char passed_fileno
[6];
566 ibcs2_interpreter
= 0;
569 elf_ex
= *((struct elfhdr
*) bprm
->buf
); /* exec-header */
574 if (elf_ex
.e_ident
[0] != 0x7f ||
575 strncmp(&elf_ex
.e_ident
[1], "ELF",3) != 0) {
579 /* First of all, some simple consistency checks */
580 if ((elf_ex
.e_type
!= ET_EXEC
&& elf_ex
.e_type
!= ET_DYN
) ||
581 (! elf_check_arch(elf_ex
.e_machine
))) {
585 /* Now read in all of the header information */
587 elf_phdata
= (struct elf_phdr
*)malloc(elf_ex
.e_phentsize
*elf_ex
.e_phnum
);
588 if (elf_phdata
== NULL
) {
592 retval
= lseek(bprm
->fd
, elf_ex
.e_phoff
, SEEK_SET
);
594 retval
= read(bprm
->fd
, (char *) elf_phdata
,
595 elf_ex
.e_phentsize
* elf_ex
.e_phnum
);
599 perror("load_elf_binary");
606 elf_ppnt
= elf_phdata
;
607 for (i
=0; i
<elf_ex
.e_phnum
; i
++, elf_ppnt
++) {
608 bswap_phdr(elf_ppnt
);
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 target_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");