1 /* Code for loading Linux executables. Mostly linux kernel code. */
3 #include "qemu/osdep.h"
5 #include "user-internals.h"
10 /* ??? This should really be somewhere else. */
11 abi_long
memcpy_to_target(abi_ulong dest
, const void *src
, unsigned long len
)
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
++) {
34 static int prepare_binprm(struct linux_binprm
*bprm
)
40 if (fstat(bprm
->fd
, &st
) < 0) {
45 if (!S_ISREG(mode
)) { /* Must be regular file */
48 if (!(mode
& 0111)) { /* Must have at least one execute bit set */
52 bprm
->e_uid
= geteuid();
53 bprm
->e_gid
= getegid();
57 bprm
->e_uid
= st
.st_uid
;
62 * If setgid is set but no group execute bit then this
63 * is a candidate for mandatory locking, not a setgid
66 if ((mode
& (S_ISGID
| S_IXGRP
)) == (S_ISGID
| S_IXGRP
)) {
67 bprm
->e_gid
= st
.st_gid
;
70 retval
= read(bprm
->fd
, bprm
->buf
, BPRM_BUF_SIZE
);
72 perror("prepare_binprm");
75 if (retval
< BPRM_BUF_SIZE
) {
76 /* Make sure the rest of the loader won't read garbage. */
77 memset(bprm
->buf
+ retval
, 0, BPRM_BUF_SIZE
- retval
);
82 /* Construct the envp and argv tables on the target stack. */
83 abi_ulong
loader_build_argptr(int envc
, int argc
, abi_ulong sp
,
84 abi_ulong stringp
, int push_ptr
)
86 TaskState
*ts
= (TaskState
*)thread_cpu
->opaque
;
87 int n
= sizeof(abi_ulong
);
95 ts
->info
->envp
= envp
;
96 ts
->info
->envc
= envc
;
97 ts
->info
->argv
= argv
;
98 ts
->info
->argc
= argc
;
101 /* FIXME - handle put_user() failures */
103 put_user_ual(envp
, sp
);
105 put_user_ual(argv
, sp
);
109 /* FIXME - handle put_user() failures */
110 put_user_ual(argc
, sp
);
112 ts
->info
->arg_strings
= stringp
;
114 /* FIXME - handle put_user() failures */
115 put_user_ual(stringp
, argv
);
117 stringp
+= target_strlen(stringp
) + 1;
119 /* FIXME - handle put_user() failures */
120 put_user_ual(0, argv
);
122 ts
->info
->env_strings
= stringp
;
124 /* FIXME - handle put_user() failures */
125 put_user_ual(stringp
, envp
);
127 stringp
+= target_strlen(stringp
) + 1;
129 /* FIXME - handle put_user() failures */
130 put_user_ual(0, envp
);
135 int loader_exec(int fdexec
, const char *filename
, char **argv
, char **envp
,
136 struct target_pt_regs
*regs
, struct image_info
*infop
,
137 struct linux_binprm
*bprm
)
142 bprm
->filename
= (char *)filename
;
143 bprm
->argc
= count(argv
);
145 bprm
->envc
= count(envp
);
148 retval
= prepare_binprm(bprm
);
151 if (bprm
->buf
[0] == 0x7f
152 && bprm
->buf
[1] == 'E'
153 && bprm
->buf
[2] == 'L'
154 && bprm
->buf
[3] == 'F') {
155 retval
= load_elf_binary(bprm
, infop
);
156 #if defined(TARGET_HAS_BFLT)
157 } else if (bprm
->buf
[0] == 'b'
158 && bprm
->buf
[1] == 'F'
159 && bprm
->buf
[2] == 'L'
160 && bprm
->buf
[3] == 'T') {
161 retval
= load_flt_binary(bprm
, infop
);
169 /* success. Initialize important registers */
170 do_init_thread(regs
, infop
);