1#include <elf.h> 2#include <poll.h> 3#include <fcntl.h> 4#include <signal.h> 5#include "syscall.h" 6#include "atomic.h" 7#include "libc.h" 8 9void __init_tls(size_t *); 10 11static void dummy(void) {} 12weak_alias(dummy, _init); 13 14__attribute__((__weak__, __visibility__("hidden"))) 15extern void (*const __init_array_start)(void), (*const __init_array_end)(void); 16 17static void dummy1(void *p) {} 18weak_alias(dummy1, __init_ssp); 19 20#define AUX_CNT 38 21 22void __init_libc(char **envp, char *pn) 23{ 24 size_t i, *auxv, aux[AUX_CNT] = { 0 }; 25 __environ = envp; 26 for (i=0; envp[i]; i++); 27 libc.auxv = auxv = (void *)(envp+i+1); 28 for (i=0; auxv[i]; i+=2) if (auxv[i]<AUX_CNT) aux[auxv[i]] = auxv[i+1]; 29 __hwcap = aux[AT_HWCAP]; 30 __sysinfo = aux[AT_SYSINFO]; 31 libc.page_size = aux[AT_PAGESZ]; 32 33 if (pn) { 34 __progname = __progname_full = pn; 35 for (i=0; pn[i]; i++) if (pn[i]=='/') __progname = pn+i+1; 36 } 37 38 __init_tls(aux); 39 __init_ssp((void *)aux[AT_RANDOM]); 40 41 if (aux[AT_UID]==aux[AT_EUID] && aux[AT_GID]==aux[AT_EGID] 42 && !aux[AT_SECURE]) return; 43 44 struct pollfd pfd[3] = { {.fd=0}, {.fd=1}, {.fd=2} }; 45#ifdef SYS_poll 46 __syscall(SYS_poll, pfd, 3, 0); 47#else 48 __syscall(SYS_ppoll, pfd, 3, &(struct timespec){0}, 0, _NSIG/8); 49#endif 50 for (i=0; i<3; i++) if (pfd[i].revents&POLLNVAL) 51 if (__sys_open("/dev/null", O_RDWR)<0) 52 a_crash(); 53 libc.secure = 1; 54} 55 56static void libc_start_init(void) 57{ 58 _init(); 59 uintptr_t a = (uintptr_t)&__init_array_start; 60 for (; a<(uintptr_t)&__init_array_end; a+=sizeof(void(*)())) 61 (*(void (**)())a)(); 62} 63 64weak_alias(libc_start_init, __libc_start_init); 65 66int __libc_start_main(int (*main)(int,char **,char **), int argc, char **argv) 67{ 68 char **envp = argv+argc+1; 69 70 __init_libc(envp, argv[0]); 71 __libc_start_init(); 72 73 /* Pass control to the application */ 74 exit(main(argc, argv, envp)); 75 return 0; 76} 77