1 /* Code for loading Linux executables. Mostly linux kernel code. */
15 /* ??? This should really be somewhere else. */
16 abi_long
memcpy_to_target(abi_ulong dest
, const void *src
,
21 host_ptr
= lock_user(VERIFY_WRITE
, dest
, len
, 0);
23 return -TARGET_EFAULT
;
24 memcpy(host_ptr
, src
, len
);
25 unlock_user(host_ptr
, dest
, 1);
29 static int in_group_p(gid_t g
)
31 /* return TRUE if we're in the specified group, FALSE otherwise */
34 gid_t grouplist
[NGROUPS
];
36 ngroup
= getgroups(NGROUPS
, grouplist
);
37 for(i
= 0; i
< ngroup
; i
++) {
38 if(grouplist
[i
] == g
) {
45 static int count(char ** vec
)
49 for(i
= 0; *vec
; i
++) {
56 static int prepare_binprm(struct linux_binprm
*bprm
)
60 int retval
, id_change
;
62 if(fstat(bprm
->fd
, &st
) < 0) {
67 if(!S_ISREG(mode
)) { /* Must be regular file */
70 if(!(mode
& 0111)) { /* Must have at least one execute bit set */
74 bprm
->e_uid
= geteuid();
75 bprm
->e_gid
= getegid();
80 bprm
->e_uid
= st
.st_uid
;
81 if(bprm
->e_uid
!= geteuid()) {
88 * If setgid is set but no group execute bit then this
89 * is a candidate for mandatory locking, not a setgid
92 if ((mode
& (S_ISGID
| S_IXGRP
)) == (S_ISGID
| S_IXGRP
)) {
93 bprm
->e_gid
= st
.st_gid
;
94 if (!in_group_p(bprm
->e_gid
)) {
99 memset(bprm
->buf
, 0, sizeof(bprm
->buf
));
100 retval
= lseek(bprm
->fd
, 0L, SEEK_SET
);
102 retval
= read(bprm
->fd
, bprm
->buf
, 128);
105 perror("prepare_binprm");
107 /* return(-errno); */
114 /* Construct the envp and argv tables on the target stack. */
115 abi_ulong
loader_build_argptr(int envc
, int argc
, abi_ulong sp
,
116 abi_ulong stringp
, int push_ptr
)
118 TaskState
*ts
= (TaskState
*)thread_env
->opaque
;
119 int n
= sizeof(abi_ulong
);
123 sp
-= (envc
+ 1) * n
;
125 sp
-= (argc
+ 1) * n
;
128 /* FIXME - handle put_user() failures */
130 put_user_ual(envp
, sp
);
132 put_user_ual(argv
, sp
);
135 /* FIXME - handle put_user() failures */
136 put_user_ual(argc
, sp
);
137 ts
->info
->arg_start
= stringp
;
139 /* FIXME - handle put_user() failures */
140 put_user_ual(stringp
, argv
);
142 stringp
+= target_strlen(stringp
) + 1;
144 ts
->info
->arg_end
= stringp
;
145 /* FIXME - handle put_user() failures */
146 put_user_ual(0, argv
);
148 /* FIXME - handle put_user() failures */
149 put_user_ual(stringp
, envp
);
151 stringp
+= target_strlen(stringp
) + 1;
153 /* FIXME - handle put_user() failures */
154 put_user_ual(0, envp
);
159 int loader_exec(const char * filename
, char ** argv
, char ** envp
,
160 struct target_pt_regs
* regs
, struct image_info
*infop
,
161 struct linux_binprm
*bprm
)
166 bprm
->p
= TARGET_PAGE_SIZE
*MAX_ARG_PAGES
-sizeof(unsigned int);
167 for (i
=0 ; i
<MAX_ARG_PAGES
; i
++) /* clear page-table */
168 bprm
->page
[i
] = NULL
;
169 retval
= open(filename
, O_RDONLY
);
173 bprm
->filename
= (char *)filename
;
174 bprm
->argc
= count(argv
);
176 bprm
->envc
= count(envp
);
179 retval
= prepare_binprm(bprm
);
181 infop
->host_argv
= argv
;
184 if (bprm
->buf
[0] == 0x7f
185 && bprm
->buf
[1] == 'E'
186 && bprm
->buf
[2] == 'L'
187 && bprm
->buf
[3] == 'F') {
188 #ifndef TARGET_HAS_ELFLOAD32
189 retval
= load_elf_binary(bprm
,regs
,infop
);
191 retval
= load_elf_binary_multi(bprm
, regs
, infop
);
193 #if defined(TARGET_HAS_BFLT)
194 } else if (bprm
->buf
[0] == 'b'
195 && bprm
->buf
[1] == 'F'
196 && bprm
->buf
[2] == 'L'
197 && bprm
->buf
[3] == 'T') {
198 retval
= load_flt_binary(bprm
,regs
,infop
);
201 fprintf(stderr
, "Unknown binary format\n");
207 /* success. Initialize important registers */
208 do_init_thread(regs
, infop
);
212 /* Something went wrong, return the inode and free the argument pages*/
213 for (i
=0 ; i
<MAX_ARG_PAGES
; i
++) {