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