1 /* execve() - basic program execution call Author: Kees J. Bot
13 #include <sys/exec_elf.h>
16 __weak_alias(execve
, _execve
)
19 int execve(const char *path
, char * const *argv
, char * const *envp
)
35 /* Assumptions: size_t and char *, it's all the same thing. */
37 /* Create a stack image that only needs to be patched up slightly
38 * by the kernel to be used for the process to be executed.
41 ov
= 0; /* No overflow yet. */
42 frame_size
= 0; /* Size of the new initial stack. */
43 string_off
= 0; /* Offset to start of the strings. */
44 argc
= 0; /* Argument count. */
46 for (ap
= argv
; *ap
!= NULL
; ap
++) {
47 n
= sizeof(*ap
) + strlen(*ap
) + 1;
49 if (frame_size
< n
) ov
= 1;
50 string_off
+= sizeof(*ap
);
54 for (ep
= envp
; *ep
!= NULL
; ep
++) {
55 n
= sizeof(*ep
) + strlen(*ep
) + 1;
57 if (frame_size
< n
) ov
= 1;
58 string_off
+= sizeof(*ap
);
61 /* Add an argument count, two terminating nulls and
62 * space for the ELF aux vectors, that must come before
63 * (i.e. at a higher address) then the strings.
65 vectors
= sizeof(argc
) + sizeof(*ap
) + sizeof(*ep
) +
66 sizeof(AuxInfo
) * PMEF_AUXVECTORS
;
67 extra
= vectors
+ PMEF_EXECNAMELEN1
;
72 frame_size
= (frame_size
+ sizeof(char *) - 1) & ~(sizeof(char *) - 1);
74 /* The party is off if there is an overflow. */
75 if (ov
|| frame_size
< 3 * sizeof(char *)) {
80 /* Allocate space for the stack frame. */
81 if ((frame
= (char *) sbrk(frame_size
)) == (char *) -1) {
86 /* Set arg count, init pointers to vector and string tables. */
87 * (size_t *) frame
= argc
;
88 vp
= (char **) (frame
+ sizeof(argc
));
89 sp
= frame
+ string_off
;
91 /* Load the argument vector and strings. */
92 for (ap
= argv
; *ap
!= NULL
; ap
++) {
93 *vp
++= (char *) (sp
- frame
);
100 /* Load the environment vector and strings. */
101 for (ep
= envp
; *ep
!= NULL
; ep
++) {
102 *vp
++= (char *) (sp
- frame
);
110 while (sp
< frame
+ frame_size
) *sp
++= 0;
112 /* Clear unused message fields */
113 memset(&m
, 0, sizeof(m
));
115 /* We can finally make the system call. */
116 m
.m1_i1
= strlen(path
) + 1;
117 m
.m1_i2
= frame_size
;
118 m
.m1_p1
= (char *) __UNCONST(path
);
121 /* Tell PM/VFS we have left space for the aux vectors
122 * and executable name
124 m
.PMEXEC_FLAGS
= PMEF_AUXVECTORSPACE
| PMEF_EXECNAMESPACE1
;
126 (void) _syscall(PM_PROC_NR
, EXEC
, &m
);
128 /* Failure, return the memory used for the frame and exit. */
129 (void) sbrk(-frame_size
);