]>
git.proxmox.com Git - qemu.git/blob - linux-user/elfload.c
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 /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
265 we allocate a bigger stack. Need a better solution, for example
266 by remapping the process stack directly at the right place */
267 if(x86_stack_size
> MAX_ARG_PAGES
*X86_PAGE_SIZE
) {
268 if((long)mmap4k((void *)(X86_STACK_TOP
-x86_stack_size
), x86_stack_size
+ X86_PAGE_SIZE
,
269 PROT_READ
| PROT_WRITE
,
270 MAP_GROWSDOWN
| MAP_FIXED
| MAP_PRIVATE
| MAP_ANONYMOUS
, -1, 0) == -1) {
276 if((long)mmap4k((void *)stack_base
, (MAX_ARG_PAGES
+1)*X86_PAGE_SIZE
,
277 PROT_READ
| PROT_WRITE
,
278 MAP_GROWSDOWN
| MAP_FIXED
| MAP_PRIVATE
| MAP_ANONYMOUS
, -1, 0) == -1) {
286 for (i
= 0 ; i
< MAX_ARG_PAGES
; i
++) {
290 memcpy((void *)stack_base
, (void *)bprm
->page
[i
], X86_PAGE_SIZE
);
291 free_page((void *)bprm
->page
[i
]);
293 stack_base
+= X86_PAGE_SIZE
;
298 static void set_brk(unsigned long start
, unsigned long end
)
300 /* page-align the start and end addresses... */
301 start
= ALPHA_PAGE_ALIGN(start
);
302 end
= ALPHA_PAGE_ALIGN(end
);
305 if((long)mmap4k(start
, end
- start
,
306 PROT_READ
| PROT_WRITE
| PROT_EXEC
,
307 MAP_FIXED
| MAP_PRIVATE
| MAP_ANONYMOUS
, -1, 0) == -1) {
308 perror("cannot mmap brk");
314 /* We need to explicitly zero any fractional pages
315 after the data section (i.e. bss). This would
316 contain the junk from the file that should not
320 static void padzero(unsigned long elf_bss
)
325 nbyte
= elf_bss
& (ALPHA_PAGE_SIZE
-1); /* was X86_PAGE_SIZE - JRP */
327 nbyte
= ALPHA_PAGE_SIZE
- nbyte
;
328 fpnt
= (char *) elf_bss
;
335 static unsigned int * create_elf_tables(char *p
, int argc
, int envc
,
336 struct elfhdr
* exec
,
337 unsigned long load_addr
,
338 unsigned long interp_load_addr
, int ibcs
,
339 struct image_info
*info
)
341 target_ulong
*argv
, *envp
, *dlinfo
;
345 * Force 16 byte alignment here for generality.
347 sp
= (unsigned int *) (~15UL & (unsigned long) p
);
348 sp
-= exec
? DLINFO_ITEMS
*2 : 2;
355 put_user(tswapl((target_ulong
)envp
),--sp
);
356 put_user(tswapl((target_ulong
)argv
),--sp
);
359 #define NEW_AUX_ENT(id, val) \
360 put_user (tswapl(id), dlinfo++); \
361 put_user (tswapl(val), dlinfo++)
363 if (exec
) { /* Put this here for an ELF program interpreter */
364 struct elf_phdr
* eppnt
;
365 eppnt
= (struct elf_phdr
*)((unsigned long)exec
->e_phoff
);
367 NEW_AUX_ENT (AT_PHDR
, (unsigned int)(load_addr
+ exec
->e_phoff
));
368 NEW_AUX_ENT (AT_PHENT
, (unsigned int)(sizeof (struct elf_phdr
)));
369 NEW_AUX_ENT (AT_PHNUM
, (unsigned int)(exec
->e_phnum
));
370 NEW_AUX_ENT (AT_PAGESZ
, (unsigned int)(ALPHA_PAGE_SIZE
));
371 NEW_AUX_ENT (AT_BASE
, (unsigned int)(interp_load_addr
));
372 NEW_AUX_ENT (AT_FLAGS
, (unsigned int)0);
373 NEW_AUX_ENT (AT_ENTRY
, (unsigned int) exec
->e_entry
);
374 NEW_AUX_ENT (AT_UID
, (unsigned int) getuid());
375 NEW_AUX_ENT (AT_EUID
, (unsigned int) geteuid());
376 NEW_AUX_ENT (AT_GID
, (unsigned int) getgid());
377 NEW_AUX_ENT (AT_EGID
, (unsigned int) getegid());
379 NEW_AUX_ENT (AT_NULL
, 0);
381 put_user(tswapl(argc
),--sp
);
382 info
->arg_start
= (unsigned int)((unsigned long)p
& 0xffffffff);
384 put_user(tswapl((target_ulong
)p
),argv
++);
385 while (get_user(p
++)) /* nothing */ ;
388 info
->arg_end
= info
->env_start
= (unsigned int)((unsigned long)p
& 0xffffffff);
390 put_user(tswapl((target_ulong
)p
),envp
++);
391 while (get_user(p
++)) /* nothing */ ;
394 info
->env_end
= (unsigned int)((unsigned long)p
& 0xffffffff);
400 static unsigned long load_elf_interp(struct elfhdr
* interp_elf_ex
,
402 unsigned long *interp_load_addr
)
404 struct elf_phdr
*elf_phdata
= NULL
;
405 struct elf_phdr
*eppnt
;
406 unsigned long load_addr
;
407 int load_addr_set
= 0;
409 unsigned long last_bss
, elf_bss
;
417 /* We put this here so that mmap will search for the *first*
418 * available memory...
420 load_addr
= INTERP_LOADADDR
;
422 /* First of all, some simple consistency checks */
423 if ((interp_elf_ex
->e_type
!= ET_EXEC
&&
424 interp_elf_ex
->e_type
!= ET_DYN
) ||
425 !elf_check_arch(interp_elf_ex
->e_machine
)) {
429 /* Now read in all of the header information */
431 if (sizeof(struct elf_phdr
) * interp_elf_ex
->e_phnum
> X86_PAGE_SIZE
)
434 elf_phdata
= (struct elf_phdr
*)
435 malloc(sizeof(struct elf_phdr
) * interp_elf_ex
->e_phnum
);
441 * If the size of this structure has changed, then punt, since
442 * we will be doing the wrong thing.
444 if (interp_elf_ex
->e_phentsize
!= sizeof(struct elf_phdr
))
450 retval
= lseek(interpreter_fd
, interp_elf_ex
->e_phoff
, SEEK_SET
);
452 retval
= read(interpreter_fd
,
454 sizeof(struct elf_phdr
) * interp_elf_ex
->e_phnum
);
458 perror("load_elf_interp");
465 for (i
=0; i
<interp_elf_ex
->e_phnum
; i
++, eppnt
++) {
470 for(i
=0; i
<interp_elf_ex
->e_phnum
; i
++, eppnt
++)
471 if (eppnt
->p_type
== PT_LOAD
) {
472 int elf_type
= MAP_PRIVATE
| MAP_DENYWRITE
;
474 unsigned long vaddr
= 0;
477 if (eppnt
->p_flags
& PF_R
) elf_prot
= PROT_READ
;
478 if (eppnt
->p_flags
& PF_W
) elf_prot
|= PROT_WRITE
;
479 if (eppnt
->p_flags
& PF_X
) elf_prot
|= PROT_EXEC
;
480 if (interp_elf_ex
->e_type
== ET_EXEC
|| load_addr_set
) {
481 elf_type
|= MAP_FIXED
;
482 vaddr
= eppnt
->p_vaddr
;
484 error
= (unsigned long)mmap4k(load_addr
+X86_ELF_PAGESTART(vaddr
),
485 eppnt
->p_filesz
+ X86_ELF_PAGEOFFSET(eppnt
->p_vaddr
),
489 eppnt
->p_offset
- X86_ELF_PAGEOFFSET(eppnt
->p_vaddr
));
491 if (error
> -1024UL) {
493 close(interpreter_fd
);
498 if (!load_addr_set
&& interp_elf_ex
->e_type
== ET_DYN
) {
504 * Find the end of the file mapping for this phdr, and keep
505 * track of the largest address we see for this.
507 k
= load_addr
+ eppnt
->p_vaddr
+ eppnt
->p_filesz
;
508 if (k
> elf_bss
) elf_bss
= k
;
511 * Do the same thing for the memory mapping - between
512 * elf_bss and last_bss is the bss section.
514 k
= load_addr
+ eppnt
->p_memsz
+ eppnt
->p_vaddr
;
515 if (k
> last_bss
) last_bss
= k
;
518 /* Now use mmap to map the library into memory. */
520 close(interpreter_fd
);
523 * Now fill out the bss section. First pad the last page up
524 * to the page boundary, and then perform a mmap to make sure
525 * that there are zeromapped pages up to and including the last
529 elf_bss
= X86_ELF_PAGESTART(elf_bss
+ ALPHA_PAGE_SIZE
- 1); /* What we have mapped so far */
531 /* Map the last of the bss segment */
532 if (last_bss
> elf_bss
) {
533 mmap4k(elf_bss
, last_bss
-elf_bss
,
534 PROT_READ
|PROT_WRITE
|PROT_EXEC
,
535 MAP_FIXED
|MAP_PRIVATE
|MAP_ANONYMOUS
, -1, 0);
539 *interp_load_addr
= load_addr
;
540 return ((unsigned long) interp_elf_ex
->e_entry
) + load_addr
;
545 static int load_elf_binary(struct linux_binprm
* bprm
, struct target_pt_regs
* regs
,
546 struct image_info
* info
)
548 struct elfhdr elf_ex
;
549 struct elfhdr interp_elf_ex
;
550 struct exec interp_ex
;
551 int interpreter_fd
= -1; /* avoid warning */
552 unsigned long load_addr
;
553 int load_addr_set
= 0;
554 unsigned int interpreter_type
= INTERPRETER_NONE
;
555 unsigned char ibcs2_interpreter
;
558 struct elf_phdr
* elf_ppnt
;
559 struct elf_phdr
*elf_phdata
;
560 unsigned long elf_bss
, k
, elf_brk
;
562 char * elf_interpreter
;
563 unsigned long elf_entry
, interp_load_addr
= 0;
565 unsigned long start_code
, end_code
, end_data
;
566 unsigned long elf_stack
;
567 char passed_fileno
[6];
569 ibcs2_interpreter
= 0;
572 elf_ex
= *((struct elfhdr
*) bprm
->buf
); /* exec-header */
577 if (elf_ex
.e_ident
[0] != 0x7f ||
578 strncmp(&elf_ex
.e_ident
[1], "ELF",3) != 0) {
582 /* First of all, some simple consistency checks */
583 if ((elf_ex
.e_type
!= ET_EXEC
&& elf_ex
.e_type
!= ET_DYN
) ||
584 (! elf_check_arch(elf_ex
.e_machine
))) {
588 /* Now read in all of the header information */
590 elf_phdata
= (struct elf_phdr
*)malloc(elf_ex
.e_phentsize
*elf_ex
.e_phnum
);
591 if (elf_phdata
== NULL
) {
595 retval
= lseek(bprm
->fd
, elf_ex
.e_phoff
, SEEK_SET
);
597 retval
= read(bprm
->fd
, (char *) elf_phdata
,
598 elf_ex
.e_phentsize
* elf_ex
.e_phnum
);
602 perror("load_elf_binary");
609 elf_ppnt
= elf_phdata
;
610 for (i
=0; i
<elf_ex
.e_phnum
; i
++, elf_ppnt
++) {
611 bswap_phdr(elf_ppnt
);
614 elf_ppnt
= elf_phdata
;
621 elf_interpreter
= NULL
;
626 for(i
=0;i
< elf_ex
.e_phnum
; i
++) {
627 if (elf_ppnt
->p_type
== PT_INTERP
) {
628 if ( elf_interpreter
!= NULL
)
631 free(elf_interpreter
);
636 /* This is the program interpreter used for
637 * shared libraries - for now assume that this
638 * is an a.out format binary
641 elf_interpreter
= (char *)malloc(elf_ppnt
->p_filesz
+strlen(X86_DEFAULT_LIB_DIR
));
643 if (elf_interpreter
== NULL
) {
649 strcpy(elf_interpreter
, X86_DEFAULT_LIB_DIR
);
650 retval
= lseek(bprm
->fd
, elf_ppnt
->p_offset
, SEEK_SET
);
652 retval
= read(bprm
->fd
,
653 elf_interpreter
+strlen(X86_DEFAULT_LIB_DIR
),
657 perror("load_elf_binary2");
661 /* If the program interpreter is one of these two,
662 then assume an iBCS2 image. Otherwise assume
663 a native linux image. */
665 /* JRP - Need to add X86 lib dir stuff here... */
667 if (strcmp(elf_interpreter
,"/usr/lib/libc.so.1") == 0 ||
668 strcmp(elf_interpreter
,"/usr/lib/ld.so.1") == 0) {
669 ibcs2_interpreter
= 1;
673 printf("Using ELF interpreter %s\n", elf_interpreter
);
676 retval
= open(elf_interpreter
, O_RDONLY
);
678 interpreter_fd
= retval
;
681 perror(elf_interpreter
);
683 /* retval = -errno; */
688 retval
= lseek(interpreter_fd
, 0, SEEK_SET
);
690 retval
= read(interpreter_fd
,bprm
->buf
,128);
694 interp_ex
= *((struct exec
*) bprm
->buf
); /* aout exec-header */
695 interp_elf_ex
=*((struct elfhdr
*) bprm
->buf
); /* elf exec-header */
698 perror("load_elf_binary3");
701 free(elf_interpreter
);
709 /* Some simple consistency checks for the interpreter */
710 if (elf_interpreter
){
711 interpreter_type
= INTERPRETER_ELF
| INTERPRETER_AOUT
;
713 /* Now figure out which format our binary is */
714 if ((N_MAGIC(interp_ex
) != OMAGIC
) && (N_MAGIC(interp_ex
) != ZMAGIC
) &&
715 (N_MAGIC(interp_ex
) != QMAGIC
)) {
716 interpreter_type
= INTERPRETER_ELF
;
719 if (interp_elf_ex
.e_ident
[0] != 0x7f ||
720 strncmp(&interp_elf_ex
.e_ident
[1], "ELF",3) != 0) {
721 interpreter_type
&= ~INTERPRETER_ELF
;
724 if (!interpreter_type
) {
725 free(elf_interpreter
);
732 /* OK, we are done with that, now set up the arg stuff,
733 and then start this sucker up */
735 if (!bprm
->sh_bang
) {
738 if (interpreter_type
== INTERPRETER_AOUT
) {
739 sprintf(passed_fileno
, "%d", bprm
->fd
);
740 passed_p
= passed_fileno
;
742 if (elf_interpreter
) {
743 bprm
->p
= copy_strings(1,&passed_p
,bprm
->page
,bprm
->p
);
748 if (elf_interpreter
) {
749 free(elf_interpreter
);
757 /* OK, This is the point of no return */
760 info
->start_mmap
= (unsigned long)ELF_START_MMAP
;
762 elf_entry
= (unsigned long) elf_ex
.e_entry
;
764 /* Do this so that we can load the interpreter, if need be. We will
765 change some of these later */
767 bprm
->p
= setup_arg_pages(bprm
->p
, bprm
, info
);
768 info
->start_stack
= bprm
->p
;
770 /* Now we do a little grungy work by mmaping the ELF image into
771 * the correct location in memory. At this point, we assume that
772 * the image should be loaded at fixed address, not at a variable
778 for(i
= 0, elf_ppnt
= elf_phdata
; i
< elf_ex
.e_phnum
; i
++, elf_ppnt
++) {
779 if (elf_ppnt
->p_type
== PT_LOAD
) {
781 if (elf_ppnt
->p_flags
& PF_R
) elf_prot
|= PROT_READ
;
782 if (elf_ppnt
->p_flags
& PF_W
) elf_prot
|= PROT_WRITE
;
783 if (elf_ppnt
->p_flags
& PF_X
) elf_prot
|= PROT_EXEC
;
785 mapped_addr
= mmap4k(X86_ELF_PAGESTART(elf_ppnt
->p_vaddr
),
786 (elf_ppnt
->p_filesz
+
787 X86_ELF_PAGEOFFSET(elf_ppnt
->p_vaddr
)),
789 (MAP_FIXED
| MAP_PRIVATE
| MAP_DENYWRITE
),
791 (elf_ppnt
->p_offset
-
792 X86_ELF_PAGEOFFSET(elf_ppnt
->p_vaddr
)));
794 if((unsigned long)mapped_addr
== 0xffffffffffffffff) {
802 if (X86_ELF_PAGESTART(elf_ppnt
->p_vaddr
) < elf_stack
)
803 elf_stack
= X86_ELF_PAGESTART(elf_ppnt
->p_vaddr
);
806 if (!load_addr_set
) {
807 load_addr
= elf_ppnt
->p_vaddr
- elf_ppnt
->p_offset
;
810 k
= elf_ppnt
->p_vaddr
;
811 if (k
< start_code
) start_code
= k
;
812 k
= elf_ppnt
->p_vaddr
+ elf_ppnt
->p_filesz
;
813 if (k
> elf_bss
) elf_bss
= k
;
815 if ((elf_ppnt
->p_flags
& PF_X
) && end_code
< k
)
817 if ( !(elf_ppnt
->p_flags
& PF_W
) && end_code
< k
)
820 if (end_data
< k
) end_data
= k
;
821 k
= elf_ppnt
->p_vaddr
+ elf_ppnt
->p_memsz
;
822 if (k
> elf_brk
) elf_brk
= k
;
826 if (elf_interpreter
) {
827 if (interpreter_type
& 1) {
828 elf_entry
= load_aout_interp(&interp_ex
, interpreter_fd
);
830 else if (interpreter_type
& 2) {
831 elf_entry
= load_elf_interp(&interp_elf_ex
, interpreter_fd
,
835 close(interpreter_fd
);
836 free(elf_interpreter
);
838 if (elf_entry
== ~0UL) {
839 printf("Unable to load interpreter\n");
848 if (interpreter_type
!= INTERPRETER_AOUT
) close(bprm
->fd
);
849 info
->personality
= (ibcs2_interpreter
? PER_SVR4
: PER_LINUX
);
852 info
->start_stack
= bprm
->p
= elf_stack
- 4;
854 bprm
->p
= (unsigned long)
855 create_elf_tables((char *)bprm
->p
,
858 (interpreter_type
== INTERPRETER_ELF
? &elf_ex
: NULL
),
861 (interpreter_type
== INTERPRETER_AOUT
? 0 : 1),
863 if (interpreter_type
== INTERPRETER_AOUT
)
864 info
->arg_start
+= strlen(passed_fileno
) + 1;
865 info
->start_brk
= info
->brk
= elf_brk
;
866 info
->end_code
= end_code
;
867 info
->start_code
= start_code
;
868 info
->end_data
= end_data
;
869 info
->start_stack
= bprm
->p
;
871 /* Calling set_brk effectively mmaps the pages that we need for the bss and break
873 set_brk(elf_bss
, elf_brk
);
878 printf("(start_brk) %x\n" , info
->start_brk
);
879 printf("(end_code) %x\n" , info
->end_code
);
880 printf("(start_code) %x\n" , info
->start_code
);
881 printf("(end_data) %x\n" , info
->end_data
);
882 printf("(start_stack) %x\n" , info
->start_stack
);
883 printf("(brk) %x\n" , info
->brk
);
886 if ( info
->personality
== PER_SVR4
)
888 /* Why this, you ask??? Well SVr4 maps page 0 as read-only,
889 and some applications "depend" upon this behavior.
890 Since we do not have the power to recompile these, we
891 emulate the SVr4 behavior. Sigh. */
892 mapped_addr
= mmap4k(NULL
, ALPHA_PAGE_SIZE
, PROT_READ
| PROT_EXEC
,
893 MAP_FIXED
| MAP_PRIVATE
, -1, 0);
898 * The ABI may specify that certain registers be set up in special
899 * ways (on i386 %edx is the address of a DT_FINI function, for
900 * example. This macro performs whatever initialization to
901 * the regs structure is required.
907 info
->entry
= elf_entry
;
914 int elf_exec(const char * filename
, char ** argv
, char ** envp
,
915 struct target_pt_regs
* regs
, struct image_info
*infop
)
917 struct linux_binprm bprm
;
921 bprm
.p
= X86_PAGE_SIZE
*MAX_ARG_PAGES
-sizeof(unsigned int);
922 for (i
=0 ; i
<MAX_ARG_PAGES
; i
++) /* clear page-table */
924 retval
= open(filename
, O_RDONLY
);
933 bprm
.filename
= (char *)filename
;
938 bprm
.argc
= count(argv
);
939 bprm
.envc
= count(envp
);
941 retval
= prepare_binprm(&bprm
);
944 bprm
.p
= copy_strings(1, &bprm
.filename
, bprm
.page
, bprm
.p
);
946 bprm
.p
= copy_strings(bprm
.envc
,envp
,bprm
.page
,bprm
.p
);
947 bprm
.p
= copy_strings(bprm
.argc
,argv
,bprm
.page
,bprm
.p
);
954 retval
= load_elf_binary(&bprm
,regs
,infop
);
957 /* success. Initialize important registers */
958 regs
->esp
= infop
->start_stack
;
959 regs
->eip
= infop
->entry
;
963 /* Something went wrong, return the inode and free the argument pages*/
964 for (i
=0 ; i
<MAX_ARG_PAGES
; i
++) {
965 free_page((void *)bprm
.page
[i
]);
971 static int load_aout_interp(void * exptr
, int interp_fd
)
973 printf("a.out interpreter not yet supported\n");