1 /* Code for loading BSD executables. Mostly linux kernel code. */
3 #include "qemu/osdep.h"
7 #define TARGET_NGROUPS 32
9 /* ??? This should really be somewhere else. */
10 abi_long
memcpy_to_target(abi_ulong dest
, const void *src
,
15 host_ptr
= lock_user(VERIFY_WRITE
, dest
, len
, 0);
17 return -TARGET_EFAULT
;
19 memcpy(host_ptr
, src
, len
);
20 unlock_user(host_ptr
, dest
, 1);
24 static int count(char **vec
)
28 for (i
= 0; *vec
; i
++) {
35 static int prepare_binprm(struct bsd_binprm
*bprm
)
41 if (fstat(bprm
->fd
, &st
) < 0) {
46 if (!S_ISREG(mode
)) { /* Must be regular file */
49 if (!(mode
& 0111)) { /* Must have at least one execute bit set */
53 bprm
->e_uid
= geteuid();
54 bprm
->e_gid
= getegid();
58 bprm
->e_uid
= st
.st_uid
;
63 * If setgid is set but no group execute bit then this
64 * is a candidate for mandatory locking, not a setgid
67 if ((mode
& (S_ISGID
| S_IXGRP
)) == (S_ISGID
| S_IXGRP
)) {
68 bprm
->e_gid
= st
.st_gid
;
71 memset(bprm
->buf
, 0, sizeof(bprm
->buf
));
72 retval
= lseek(bprm
->fd
, 0L, SEEK_SET
);
74 retval
= read(bprm
->fd
, bprm
->buf
, 128);
77 perror("prepare_binprm");
84 /* Construct the envp and argv tables on the target stack. */
85 abi_ulong
loader_build_argptr(int envc
, int argc
, abi_ulong sp
,
86 abi_ulong stringp
, int push_ptr
)
88 int n
= sizeof(abi_ulong
);
97 /* FIXME - handle put_user() failures */
99 put_user_ual(envp
, sp
);
101 put_user_ual(argv
, sp
);
104 /* FIXME - handle put_user() failures */
105 put_user_ual(argc
, sp
);
108 /* FIXME - handle put_user() failures */
109 put_user_ual(stringp
, argv
);
111 stringp
+= target_strlen(stringp
) + 1;
113 /* FIXME - handle put_user() failures */
114 put_user_ual(0, argv
);
116 /* FIXME - handle put_user() failures */
117 put_user_ual(stringp
, envp
);
119 stringp
+= target_strlen(stringp
) + 1;
121 /* FIXME - handle put_user() failures */
122 put_user_ual(0, envp
);
127 int loader_exec(const char *filename
, char **argv
, char **envp
,
128 struct target_pt_regs
*regs
, struct image_info
*infop
)
130 struct bsd_binprm bprm
;
134 bprm
.p
= TARGET_PAGE_SIZE
* MAX_ARG_PAGES
- sizeof(unsigned int);
135 for (i
= 0 ; i
< MAX_ARG_PAGES
; i
++) { /* clear page-table */
138 retval
= open(filename
, O_RDONLY
);
143 bprm
.filename
= (char *)filename
;
144 bprm
.argc
= count(argv
);
146 bprm
.envc
= count(envp
);
149 retval
= prepare_binprm(&bprm
);
152 if (bprm
.buf
[0] == 0x7f
153 && bprm
.buf
[1] == 'E'
154 && bprm
.buf
[2] == 'L'
155 && bprm
.buf
[3] == 'F') {
156 retval
= load_elf_binary(&bprm
, regs
, infop
);
158 fprintf(stderr
, "Unknown binary format\n");
164 /* success. Initialize important registers */
165 do_init_thread(regs
, infop
);
169 /* Something went wrong, return the inode and free the argument pages*/
170 for (i
= 0 ; i
< MAX_ARG_PAGES
; i
++) {
171 g_free(bprm
.page
[i
]);