1570af302Sopenharmony_ci#include <elf.h> 2570af302Sopenharmony_ci#include <poll.h> 3570af302Sopenharmony_ci#include <fcntl.h> 4570af302Sopenharmony_ci#include <signal.h> 5570af302Sopenharmony_ci#include <unistd.h> 6570af302Sopenharmony_ci#include "syscall.h" 7570af302Sopenharmony_ci#include "atomic.h" 8570af302Sopenharmony_ci#include "libc.h" 9570af302Sopenharmony_ci#include "pthread_impl.h" 10570af302Sopenharmony_ci 11570af302Sopenharmony_cistatic void dummy(void) {} 12570af302Sopenharmony_ciweak_alias(dummy, _init); 13570af302Sopenharmony_ci 14570af302Sopenharmony_ciextern weak hidden void (*const __init_array_start)(void), (*const __init_array_end)(void); 15570af302Sopenharmony_ci#ifdef __LITEOS_DEBUG__ 16570af302Sopenharmony_ciextern void parse_argv(int, char **); 17570af302Sopenharmony_ci#endif 18570af302Sopenharmony_cistatic void dummy1(void *p) {} 19570af302Sopenharmony_ciweak_alias(dummy1, __init_ssp); 20570af302Sopenharmony_ci 21570af302Sopenharmony_ci#define AUX_CNT 38 22570af302Sopenharmony_ci 23570af302Sopenharmony_ci#ifdef __GNUC__ 24570af302Sopenharmony_ci__attribute__((__noinline__)) 25570af302Sopenharmony_ci#endif 26570af302Sopenharmony_civoid __init_libc(char **envp, char *pn) 27570af302Sopenharmony_ci{ 28570af302Sopenharmony_ci size_t i, *auxv, aux[AUX_CNT] = { 0 }; 29570af302Sopenharmony_ci __environ = envp; 30570af302Sopenharmony_ci for (i=0; envp[i]; i++); 31570af302Sopenharmony_ci libc.auxv = auxv = (void *)(envp+i+1); 32570af302Sopenharmony_ci for (i=0; auxv[i]; i+=2) if (auxv[i]<AUX_CNT) aux[auxv[i]] = auxv[i+1]; 33570af302Sopenharmony_ci __hwcap = aux[AT_HWCAP]; 34570af302Sopenharmony_ci if (aux[AT_SYSINFO]) __sysinfo = aux[AT_SYSINFO]; 35570af302Sopenharmony_ci libc.page_size = aux[AT_PAGESZ]; 36570af302Sopenharmony_ci 37570af302Sopenharmony_ci if (!pn) pn = (void*)aux[AT_EXECFN]; 38570af302Sopenharmony_ci if (!pn) pn = ""; 39570af302Sopenharmony_ci __progname = __progname_full = pn; 40570af302Sopenharmony_ci for (i=0; pn[i]; i++) if (pn[i]=='/') __progname = pn+i+1; 41570af302Sopenharmony_ci 42570af302Sopenharmony_ci __init_tls(aux); 43570af302Sopenharmony_ci __init_ssp((void *)aux[AT_RANDOM]); 44570af302Sopenharmony_ci 45570af302Sopenharmony_ci if (aux[AT_UID]==aux[AT_EUID] && aux[AT_GID]==aux[AT_EGID] 46570af302Sopenharmony_ci && !aux[AT_SECURE]) return; 47570af302Sopenharmony_ci 48570af302Sopenharmony_ci struct pollfd pfd[3] = { {.fd=0}, {.fd=1}, {.fd=2} }; 49570af302Sopenharmony_ci int r = 50570af302Sopenharmony_ci#ifdef SYS_poll 51570af302Sopenharmony_ci __syscall(SYS_poll, pfd, 3, 0); 52570af302Sopenharmony_ci#else 53570af302Sopenharmony_ci __syscall(SYS_ppoll, pfd, 3, &(struct timespec){0}, 0, _NSIG/8); 54570af302Sopenharmony_ci#endif 55570af302Sopenharmony_ci if (r<0) a_crash(); 56570af302Sopenharmony_ci for (i=0; i<3; i++) if (pfd[i].revents&POLLNVAL) 57570af302Sopenharmony_ci if (__sys_open("/dev/null", O_RDWR)<0) 58570af302Sopenharmony_ci a_crash(); 59570af302Sopenharmony_ci libc.secure = 1; 60570af302Sopenharmony_ci} 61570af302Sopenharmony_ci 62570af302Sopenharmony_cistatic void libc_start_init(void) 63570af302Sopenharmony_ci{ 64570af302Sopenharmony_ci _init(); 65570af302Sopenharmony_ci uintptr_t a = (uintptr_t)&__init_array_start; 66570af302Sopenharmony_ci for (; a<(uintptr_t)&__init_array_end; a+=sizeof(void(*)())) 67570af302Sopenharmony_ci (*(void (**)(void))a)(); 68570af302Sopenharmony_ci} 69570af302Sopenharmony_ci 70570af302Sopenharmony_ciweak_alias(libc_start_init, __libc_start_init); 71570af302Sopenharmony_ci 72570af302Sopenharmony_citypedef int lsm2_fn(int (*)(int,char **,char **), int, char **); 73570af302Sopenharmony_cistatic lsm2_fn libc_start_main_stage2; 74570af302Sopenharmony_ci 75570af302Sopenharmony_ci#ifdef ENABLE_HWASAN 76570af302Sopenharmony_ciweak void __hwasan_library_loaded(unsigned long int base, const Elf64_Phdr* phdr, int phnum); 77570af302Sopenharmony_ciweak void __hwasan_library_unloaded(unsigned long int base, const Elf64_Phdr* phdr, int phnum); 78570af302Sopenharmony_ciweak void __hwasan_init(); 79570af302Sopenharmony_ci#endif 80570af302Sopenharmony_ci 81570af302Sopenharmony_ciint __libc_start_main(int (*main)(int,char **,char **), int argc, char **argv, 82570af302Sopenharmony_ci void (*init_dummy)(), void(*fini_dummy)(), void(*ldso_dummy)()) 83570af302Sopenharmony_ci{ 84570af302Sopenharmony_ci char **envp = argv+argc+1; 85570af302Sopenharmony_ci 86570af302Sopenharmony_ci#ifdef ENABLE_HWASAN 87570af302Sopenharmony_ci libc.load_hook = __hwasan_library_loaded; 88570af302Sopenharmony_ci libc.unload_hook = __hwasan_library_unloaded; 89570af302Sopenharmony_ci __hwasan_init(); 90570af302Sopenharmony_ci#endif 91570af302Sopenharmony_ci /* External linkage, and explicit noinline attribute if available, 92570af302Sopenharmony_ci * are used to prevent the stack frame used during init from 93570af302Sopenharmony_ci * persisting for the entire process lifetime. */ 94570af302Sopenharmony_ci __init_libc(envp, argv[0]); 95570af302Sopenharmony_ci 96570af302Sopenharmony_ci /* Barrier against hoisting application code or anything using ssp 97570af302Sopenharmony_ci * or thread pointer prior to its initialization above. */ 98570af302Sopenharmony_ci lsm2_fn *stage2 = libc_start_main_stage2; 99570af302Sopenharmony_ci __asm__ ( "" : "+r"(stage2) : : "memory" ); 100570af302Sopenharmony_ci return stage2(main, argc, argv); 101570af302Sopenharmony_ci} 102570af302Sopenharmony_ci 103570af302Sopenharmony_cistatic int libc_start_main_stage2(int (*main)(int,char **,char **), int argc, char **argv) 104570af302Sopenharmony_ci{ 105570af302Sopenharmony_ci char **envp = argv+argc+1; 106570af302Sopenharmony_ci __libc_start_init(); 107570af302Sopenharmony_ci#ifdef RESERVE_SIGNAL_STACK 108570af302Sopenharmony_ci pthread_reserve_signal_stack(); 109570af302Sopenharmony_ci#endif 110570af302Sopenharmony_ci errno = 0; 111570af302Sopenharmony_ci 112570af302Sopenharmony_ci#ifdef __LITEOS_A__ 113570af302Sopenharmony_ci __sig_init(); 114570af302Sopenharmony_ci#endif 115570af302Sopenharmony_ci 116570af302Sopenharmony_ci#ifdef __LITEOS_DEBUG__ 117570af302Sopenharmony_ci parse_argv(argc, argv); 118570af302Sopenharmony_ci#endif 119570af302Sopenharmony_ci 120570af302Sopenharmony_ci /* Pass control to the application */ 121570af302Sopenharmony_ci exit(main(argc, argv, envp)); 122570af302Sopenharmony_ci return 0; 123570af302Sopenharmony_ci} 124