exec.c (3324B)
1 /* $Id: //depot/blt/lib/libposix/exec.c#1 $ 2 ** 3 ** Copyright 1999 Sidney Cammeresi 4 ** All rights reserved. 5 ** 6 ** Redistribution and use in source and binary forms, with or without 7 ** modification, are permitted provided that the following conditions 8 ** are met: 9 ** 1. Redistributions of source code must retain the above copyright 10 ** notice, this list of conditions, and the following disclaimer. 11 ** 2. Redistributions in binary form must reproduce the above copyright 12 ** notice, this list of conditions, and the following disclaimer in the 13 ** documentation and/or other materials provided with the distribution. 14 ** 3. The name of the author may not be used to endorse or promote products 15 ** derived from this software without specific prior written permission. 16 ** 17 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <string.h> 30 #include <fcntl.h> 31 #include <unistd.h> 32 #include <errno.h> 33 #include <elf.h> 34 #include <sys/stat.h> 35 #include <blt/syscall.h> 36 #include <blt/libsyms.h> 37 38 weak_alias (_execve, execve) 39 40 int _execve (const char *path, char * const *argv, char * const *envp) 41 { 42 char *ptr, *c; 43 char **n_argv; 44 int i, j, fd, area, sarea, res, size, total; 45 unsigned int *magic; 46 struct stat buf; 47 uint32 *stack, *top; 48 49 res = _stat (path, &buf); 50 if (res) 51 { 52 errno = ENOENT; 53 return -1; 54 } 55 size = (buf.st_size & 0xfff) ? (buf.st_size & 0xfffff000) + 0x1000 : 56 buf.st_size; 57 fd = _open (path, O_RDONLY, 0); 58 if (fd < 0) 59 { 60 errno = ENOENT; 61 return -1; 62 } 63 area = area_create (size, 0, (void **) &ptr, 0); 64 res = _read (fd, ptr, size); 65 magic = (unsigned int *) ptr; 66 if (*magic != ELF_MAGIC) 67 { 68 errno = ENOEXEC; 69 area_destroy (area); 70 return -1; 71 } 72 // _close(fd); 73 74 /* compute how much stack we need for arguments */ 75 for (i = total = 0; argv[i] != NULL; i++) 76 total += strlen (argv[i]) + 1; 77 total = (total & ~3) ? (total & ~3) + 4 : total; 78 79 /* create stack */ 80 sarea = area_create (0x1000, 0, (void **) &stack, 0); 81 82 /* copy arguments and set up the argv array */ 83 c = (char *) stack + 0xffc - total; 84 n_argv = (char **) (c - i * sizeof (char *)); 85 for (j = 0; j < i; j++) 86 { 87 strcpy (c, argv[j]); 88 n_argv[j] = (char *) (0x3ff000 + ((unsigned int) c & 0xfff)); 89 c += strlen (argv[j]) + 1; 90 } 91 92 /* drop argc and argv on the top */ 93 top = (uint32 *) ((unsigned int) stack + 0x1000 - (total + (i + 3) * 94 sizeof (char *))); 95 top[0] = i; 96 top[1] = 0x3ff000 + (((uint32) top + 8) & 0xfff); 97 98 /* off we go */ 99 res = thr_spawn (0x1074, 0x3ff000 + ((unsigned int) top & 0xfff) + 0x10, 100 area, 0x1000, sarea, 0x3ff000, argv[0]); 101 102 /* clean up */ 103 area_destroy (area); 104 area_destroy (sarea); 105 return res; 106 } 107