1#define _GNU_SOURCE
2#define SYSCALL_NO_TLS 1
3
4#include "dynlink.h"
5
6#include <stdbool.h>
7#include <stdlib.h>
8#include <stdarg.h>
9#include <stddef.h>
10#include <string.h>
11#include <unistd.h>
12#include <stdint.h>
13#include <elf.h>
14#include <sys/mman.h>
15#include <limits.h>
16#include <fcntl.h>
17#include <sys/stat.h>
18#include <errno.h>
19#include <link.h>
20#include <setjmp.h>
21#include <pthread.h>
22#include <ctype.h>
23#include <dlfcn.h>
24#include <semaphore.h>
25#include <sys/membarrier.h>
26#include <sys/time.h>
27#include <time.h>
28#include <sys/prctl.h>
29#include <sys/queue.h>
30
31#include "cfi.h"
32#include "dlfcn_ext.h"
33#include "dynlink_rand.h"
34#include "ld_log.h"
35#include "libc.h"
36#include "musl_fdsan.h"
37#include "namespace.h"
38#include "ns_config.h"
39#include "pthread_impl.h"
40#include "fork_impl.h"
41#include "strops.h"
42#include "trace/trace_marker.h"
43
44#ifdef OHOS_ENABLE_PARAMETER
45#include "sys_param.h"
46#endif
47#ifdef LOAD_ORDER_RANDOMIZATION
48#include "zip_archive.h"
49#endif
50
51#define malloc __libc_malloc
52#define calloc __libc_calloc
53#define realloc __libc_realloc
54#define free __libc_free
55
56static void error(const char *, ...);
57
58#define MAXP2(a,b) (-(-(a)&-(b)))
59#define ALIGN(x,y) ((x)+(y)-1 & -(y))
60#define GNU_HASH_FILTER(ght, ghm, gho)                \
61	const size_t *bloomwords = (const void *)(ght+4); \
62	size_t f = bloomwords[gho & (ght[2]-1)];          \
63	if (!(f & ghm)) continue;                         \
64	f >>= (gh >> ght[3]) % (8 * sizeof f);            \
65	if (!(f & 1)) continue;
66
67#define container_of(p,t,m) ((t*)((char *)(p)-offsetof(t,m)))
68#define countof(a) ((sizeof (a))/(sizeof (a)[0]))
69#define DSO_FLAGS_NODELETE 0x1
70
71#ifdef HANDLE_RANDOMIZATION
72#define NEXT_DYNAMIC_INDEX 2
73#define MIN_DEPS_COUNT 2
74#define NAME_INDEX_ZERO 0
75#define NAME_INDEX_ONE 1
76#define NAME_INDEX_TWO 2
77#define NAME_INDEX_THREE 3
78#define TLS_CNT_INCREASE 3
79#define INVALID_FD_INHIBIT_FURTHER_SEARCH (-2)
80#endif
81
82#define PARENTS_BASE_CAPACITY 8
83#define RELOC_CAN_SEARCH_DSO_BASE_CAPACITY 32
84#define ANON_NAME_MAX_LEN 70
85
86#define KPMD_SIZE (1UL << 21)
87#define HUGEPAGES_SUPPORTED_STR_SIZE (32)
88
89#ifdef UNIT_TEST_STATIC
90    #define UT_STATIC
91#else
92    #define UT_STATIC static
93#endif
94
95/* Used for dlclose */
96#define UNLOAD_NR_DLOPEN_CHECK 1
97#define UNLOAD_COMMON_CHECK 2
98#define UNLOAD_ALL_CHECK 3
99struct dso_entry {
100	struct dso *dso;
101	TAILQ_ENTRY(dso_entry) entries;
102};
103
104struct debug {
105	int ver;
106	void *head;
107	void (*bp)(void);
108	int state;
109	void *base;
110};
111
112struct reserved_address_params {
113	void* start_addr;
114	size_t reserved_size;
115	bool must_use_reserved;
116	bool reserved_address_recursive;
117#ifdef LOAD_ORDER_RANDOMIZATION
118	struct dso *target;
119#endif
120};
121
122typedef void (*stage3_func)(size_t *, size_t *, size_t *);
123
124static struct builtin_tls {
125	char c[8];
126	struct pthread pt;
127	void *space[16];
128} builtin_tls[1];
129#define MIN_TLS_ALIGN offsetof(struct builtin_tls, pt)
130
131#define ADDEND_LIMIT 4096
132static size_t *saved_addends, *apply_addends_to;
133static bool g_is_asan;
134static struct dso ldso;
135static struct dso *head, *tail, *fini_head, *syms_tail, *lazy_head;
136static struct dso_debug_info *debug_tail = NULL;
137static char *env_path, *sys_path;
138static unsigned long long gencnt;
139static int runtime;
140static int ldd_mode;
141static int ldso_fail;
142static int noload;
143static int shutting_down;
144static jmp_buf *rtld_fail;
145static pthread_rwlock_t lock;
146static struct debug debug;
147static struct tls_module *tls_tail;
148static size_t tls_cnt, tls_offset, tls_align = MIN_TLS_ALIGN;
149static size_t static_tls_cnt;
150static pthread_mutex_t init_fini_lock;
151static pthread_cond_t ctor_cond;
152static struct dso *builtin_deps[2];
153static struct dso *const no_deps[1];
154static struct dso *builtin_ctor_queue[4];
155static struct dso **main_ctor_queue;
156static struct fdpic_loadmap *app_loadmap;
157static struct fdpic_dummy_loadmap app_dummy_loadmap;
158
159struct debug *_dl_debug_addr = &debug;
160
161extern hidden int __malloc_replaced;
162
163hidden void (*const __init_array_start)(void)=0, (*const __fini_array_start)(void)=0;
164
165extern hidden void (*const __init_array_end)(void), (*const __fini_array_end)(void);
166
167#ifdef USE_GWP_ASAN
168extern bool init_gwp_asan_by_libc(bool force_init);
169#endif
170
171weak_alias(__init_array_start, __init_array_end);
172weak_alias(__fini_array_start, __fini_array_end);
173#ifdef DFX_SIGNAL_LIBC
174UT_STATIC void __InstallSignalHandler()
175{
176}
177weak_alias(__InstallSignalHandler, DFX_InstallSignalHandler);
178#endif
179
180#ifdef HANDLE_RANDOMIZATION
181static int do_dlclose(struct dso *p);
182#endif
183
184#ifdef LOAD_ORDER_RANDOMIZATION
185static bool map_library_header(struct loadtask *task);
186static bool task_map_library(struct loadtask *task, struct reserved_address_params *reserved_params);
187static bool resolve_fd_to_realpath(struct loadtask *task);
188static bool load_library_header(struct loadtask *task);
189static void task_load_library(struct loadtask *task, struct reserved_address_params *reserved_params);
190static void preload_direct_deps(struct dso *p, ns_t *namespace, struct loadtasks *tasks);
191static void unmap_preloaded_sections(struct loadtasks *tasks);
192static void preload_deps(struct dso *p, struct loadtasks *tasks);
193static void run_loadtasks(struct loadtasks *tasks, struct reserved_address_params *reserved_params);
194UT_STATIC void assign_tls(struct dso *p);
195UT_STATIC void load_preload(char *s, ns_t *ns, struct loadtasks *tasks);
196static void open_library_by_path(const char *name, const char *s, struct loadtask *task, struct zip_info *z_info);
197static void handle_asan_path_open_by_task(int fd, const char *name, ns_t *namespace, struct loadtask *task, struct zip_info *z_info);
198#endif
199
200extern int __close(int fd);
201
202/* Sharing relro */
203static void handle_relro_sharing(struct dso *p, const dl_extinfo *extinfo, ssize_t *relro_fd_offset);
204
205/* asan path open */
206int handle_asan_path_open(int fd, const char *name, ns_t *namespace, char *buf, size_t buf_size);
207
208static void set_bss_vma_name(char *path_name, void *addr, size_t zeromap_size);
209
210static void find_and_set_bss_name(struct dso *p);
211
212/* lldb debug function */
213static void sync_with_debugger();
214static void notify_addition_to_debugger(struct dso *p);
215static void notify_remove_to_debugger(struct dso *p);
216static void add_dso_info_to_debug_map(struct dso *p);
217static void remove_dso_info_from_debug_map(struct dso *p);
218
219/* add namespace function */
220static void get_sys_path(ns_configor *conf);
221static void dlclose_ns(struct dso *p);
222static bool get_app_path(char *path, size_t size)
223{
224	int l = 0;
225	l = readlink("/proc/self/exe", path, size);
226	if (l < 0 || l >= size) {
227		LD_LOGD("get_app_path readlink failed!");
228		return false;
229	}
230	path[l] = 0;
231	LD_LOGD("get_app_path path:%{public}s.", path);
232	return true;
233}
234
235static void init_default_namespace(struct dso *app)
236{
237	ns_t *default_ns = get_default_ns();
238	memset(default_ns, 0, sizeof *default_ns);
239	ns_set_name(default_ns, NS_DEFAULT_NAME);
240	if (env_path) ns_set_env_paths(default_ns, env_path);
241	ns_set_lib_paths(default_ns, sys_path);
242	ns_set_separated(default_ns, false);
243	app->namespace = default_ns;
244	ns_add_dso(default_ns, app);
245	LD_LOGD("init_default_namespace default_namespace:"
246			"nsname: default ,"
247			"lib_paths:%{public}s ,"
248			"env_path:%{public}s ,"
249			"separated: false.",
250			sys_path, env_path);
251	return;
252}
253
254UT_STATIC void set_ns_attrs(ns_t *ns, ns_configor *conf)
255{
256	if(!ns || !conf) {
257		return;
258	}
259
260	char *lib_paths, *asan_lib_paths, *permitted_paths, *asan_permitted_paths, *allowed_libs;
261
262	ns_set_separated(ns, conf->get_separated(ns->ns_name));
263
264	lib_paths = conf->get_lib_paths(ns->ns_name);
265	if (lib_paths) ns_set_lib_paths(ns, lib_paths);
266
267	asan_lib_paths = conf->get_asan_lib_paths(ns->ns_name);
268	if (asan_lib_paths) ns_set_asan_lib_paths(ns, asan_lib_paths);
269
270	permitted_paths = conf->get_permitted_paths(ns->ns_name);
271	if (permitted_paths) ns_set_permitted_paths(ns, permitted_paths);
272
273	asan_permitted_paths = conf->get_asan_permitted_paths(ns->ns_name);
274	if (asan_permitted_paths) ns_set_asan_permitted_paths(ns, asan_permitted_paths);
275
276	allowed_libs = conf->get_allowed_libs(ns->ns_name);
277	if (allowed_libs) ns_set_allowed_libs(ns, allowed_libs);
278
279	LD_LOGD("set_ns_attrs :"
280			"ns_name: %{public}s ,"
281			"separated:%{public}d ,"
282			"lib_paths:%{public}s ,"
283			"asan_lib_paths:%{public}s ,"
284			"permitted_paths:%{public}s ,"
285			"asan_permitted_paths:%{public}s ,"
286			"allowed_libs: %{public}s .",
287			ns->ns_name, ns->separated, ns->lib_paths, ns->asan_lib_paths, permitted_paths,
288			asan_permitted_paths, allowed_libs);
289}
290
291UT_STATIC void set_ns_inherits(ns_t *ns, ns_configor *conf)
292{
293	if(!ns || !conf) {
294		return;
295	}
296
297	strlist *inherits = conf->get_inherits(ns->ns_name);
298	if (inherits) {
299		for (size_t i=0; i<inherits->num; i++) {
300			ns_t *inherited_ns = find_ns_by_name(inherits->strs[i]);
301			if (inherited_ns) {
302				char *shared_libs = conf->get_inherit_shared_libs(ns->ns_name, inherited_ns->ns_name);
303				ns_add_inherit(ns, inherited_ns, shared_libs);
304				LD_LOGD("set_ns_inherits :"
305						"ns_name: %{public}s ,"
306						"separated:%{public}d ,"
307						"lib_paths:%{public}s ,"
308						"asan_lib_paths:%{public}s ,",
309						inherited_ns->ns_name, inherited_ns->separated, inherited_ns->lib_paths,
310						inherited_ns->asan_lib_paths);
311			}
312		}
313		strlist_free(inherits);
314	} else {
315		LD_LOGD("set_ns_inherits inherits is NULL!");
316	}
317}
318
319static void init_namespace(struct dso *app)
320{
321	char app_path[PATH_MAX+1];
322	if (!get_app_path(app_path, sizeof app_path)) {
323		strcpy(app_path, app->name);
324	}
325	char *t = strrchr(app_path, '/');
326	if (t) {
327		*t = 0;
328	} else {
329		app_path[0] = '.';
330		app_path[1] = 0;
331	}
332
333	nslist *nsl = nslist_init();
334	ns_configor *conf = configor_init();
335	char file_path[sizeof "/etc/ld-musl-namespace-" + sizeof (LDSO_ARCH) + sizeof ".ini" + 1] = {0};
336	(void)snprintf(file_path, sizeof file_path, "/etc/ld-musl-namespace-%s.ini", LDSO_ARCH);
337	LD_LOGI("init_namespace file_path:%{public}s", file_path);
338	trace_marker_reset();
339	trace_marker_begin(HITRACE_TAG_MUSL, "parse linker config", file_path);
340	int ret = conf->parse(file_path, app_path);
341	if (ret < 0) {
342		LD_LOGE("init_namespace ini file parse failed!");
343		/* Init_default_namespace is required even if the ini file parsing fails */
344		if (!sys_path) get_sys_path(conf);
345		init_default_namespace(app);
346		configor_free();
347		trace_marker_end(HITRACE_TAG_MUSL);
348		return;
349	}
350
351	/* sys_path needs to be parsed through ini file */
352	if (!sys_path) get_sys_path(conf);
353	init_default_namespace(app);
354
355	/* Init default namespace */
356	ns_t *d_ns = get_default_ns();
357	set_ns_attrs(d_ns, conf);
358
359	/* Init other namespace */
360	if (!nsl) {
361		LD_LOGE("init nslist fail!");
362		configor_free();
363		trace_marker_end(HITRACE_TAG_MUSL);
364		return;
365	}
366	strlist *s_ns = conf->get_namespaces();
367	if (s_ns) {
368		for (size_t i=0; i<s_ns->num; i++) {
369			ns_t *ns = ns_alloc();
370			ns_set_name(ns, s_ns->strs[i]);
371			set_ns_attrs(ns, conf);
372			ns_add_dso(ns, app);
373			nslist_add_ns(ns);
374		}
375		strlist_free(s_ns);
376	}
377	/* Set inherited namespace */
378	set_ns_inherits(d_ns, conf);
379	for (size_t i = 0; i < nsl->num; i++) {
380		set_ns_inherits(nsl->nss[i], conf);
381	}
382	configor_free();
383	trace_marker_end(HITRACE_TAG_MUSL);
384	return;
385}
386
387/* Compute load address for a virtual address in a given dso. */
388#if DL_FDPIC
389void *laddr(const struct dso *p, size_t v)
390{
391	size_t j=0;
392	if (!p->loadmap) return p->base + v;
393	for (j=0; v-p->loadmap->segs[j].p_vaddr >= p->loadmap->segs[j].p_memsz; j++);
394	return (void *)(v - p->loadmap->segs[j].p_vaddr + p->loadmap->segs[j].addr);
395}
396static void *laddr_pg(const struct dso *p, size_t v)
397{
398	size_t j=0;
399	size_t pgsz = PAGE_SIZE;
400	if (!p->loadmap) return p->base + v;
401	for (j=0; ; j++) {
402		size_t a = p->loadmap->segs[j].p_vaddr;
403		size_t b = a + p->loadmap->segs[j].p_memsz;
404		a &= -pgsz;
405		b += pgsz-1;
406		b &= -pgsz;
407		if (v-a<b-a) break;
408	}
409	return (void *)(v - p->loadmap->segs[j].p_vaddr + p->loadmap->segs[j].addr);
410}
411static void (*fdbarrier(void *p))()
412{
413	void (*fd)();
414	__asm__("" : "=r"(fd) : "0"(p));
415	return fd;
416}
417#define fpaddr(p, v) fdbarrier((&(struct funcdesc){ \
418	laddr(p, v), (p)->got }))
419#else
420#define laddr(p, v) (void *)((p)->base + (v))
421#define laddr_pg(p, v) laddr(p, v)
422#define fpaddr(p, v) ((void (*)())laddr(p, v))
423#endif
424
425static void decode_vec(size_t *v, size_t *a, size_t cnt)
426{
427	size_t i;
428	for (i=0; i<cnt; i++) a[i] = 0;
429	for (; v[0]; v+=2) if (v[0]-1<cnt-1) {
430		if (v[0] < 8*sizeof(long)) {
431			a[0] |= 1UL<<v[0];
432		}
433		a[v[0]] = v[1];
434	}
435}
436
437static int search_vec(size_t *v, size_t *r, size_t key)
438{
439	for (; v[0]!=key; v+=2)
440		if (!v[0]) return 0;
441	*r = v[1];
442	return 1;
443}
444
445UT_STATIC int check_vna_hash(Verdef *def, int16_t vsym, uint32_t vna_hash)
446{
447	int matched = 0;
448
449	vsym &= 0x7fff;
450	Verdef *verdef = def;
451	for(;;) {
452		if ((verdef->vd_ndx & 0x7fff) == vsym) {
453			if (vna_hash == verdef->vd_hash) {
454				matched = 1;
455			}
456			break;
457		}
458		if (matched) {
459			break;
460		}
461		if (verdef->vd_next == 0) {
462			break;
463		}
464		verdef = (Verdef *)((char *)verdef + verdef->vd_next);
465	}
466#if (LD_LOG_LEVEL & LD_LOG_DEBUG)
467	if (!matched) {
468		LD_LOGD("check_vna_hash no matched found. vsym=%{public}d vna_hash=%{public}x", vsym, vna_hash);
469	}
470#endif
471	return matched;
472}
473
474UT_STATIC int check_verinfo(Verdef *def, int16_t *versym, uint32_t index, struct verinfo *verinfo, char *strings)
475{
476	/* if the versym and verinfo is null , then not need version. */
477	if (!versym || !def) {
478		if (strlen(verinfo->v) == 0) {
479			return 1;
480		} else {
481			LD_LOGD("check_verinfo versym or def is null and verinfo->v exist, s:%{public}s v:%{public}s.",
482				verinfo->s, verinfo->v);
483			return 0;
484		}
485	}
486
487	int16_t vsym = versym[index];
488
489	/* find the verneed symbol. */
490	if (verinfo->use_vna_hash) {
491		if (vsym != VER_NDX_LOCAL && versym != VER_NDX_GLOBAL) {
492			return check_vna_hash(def, vsym, verinfo->vna_hash);
493		}
494	}
495
496	/* if the version length is zero and vsym not less than zero, then library hava default version symbol. */
497	if (strlen(verinfo->v) == 0) {
498		if (vsym >= 0) {
499			return 1;
500		} else {
501			LD_LOGD("check_verinfo not default version. vsym:%{public}d s:%{public}s", vsym, verinfo->s);
502			return 0;
503		}
504	}
505
506	/* find the version of symbol. */
507	vsym &= 0x7fff;
508	for (;;) {
509		if (!(def->vd_flags & VER_FLG_BASE) && (def->vd_ndx & 0x7fff) == vsym) {
510			break;
511		}
512		if (def->vd_next == 0) {
513			return 0;
514		}
515		def = (Verdef *)((char *)def + def->vd_next);
516	}
517
518	Verdaux *aux = (Verdaux *)((char *)def + def->vd_aux);
519
520	int ret = !strcmp(verinfo->v, strings + aux->vda_name);
521#if (LD_LOG_LEVEL & LD_LOG_DEBUG)
522	if (!ret) {
523		LD_LOGD("check_verinfo version not match. s=%{public}s v=%{public}s vsym=%{public}d vda_name=%{public}s",
524			verinfo->s, verinfo->v, vsym, strings + aux->vda_name);
525	}
526#endif
527	return ret;
528}
529
530static struct sym_info_pair sysv_hash(const char *s0)
531{
532	struct sym_info_pair s_info_p;
533	const unsigned char *s = (void *)s0;
534	uint_fast32_t h = 0;
535	while (*s) {
536		h = 16*h + *s++;
537		h ^= h>>24 & 0xf0;
538	}
539	s_info_p.sym_h = h & 0xfffffff;
540	s_info_p.sym_l = (char *)s - s0;
541	return s_info_p;
542}
543
544struct sym_info_pair gnu_hash(const char *s0)
545{
546	struct sym_info_pair s_info_p;
547	const unsigned char *s = (void *)s0;
548	uint_fast32_t h = 5381;
549	for (; *s; s++)
550		h += h*32 + *s;
551	s_info_p.sym_h = h;
552	s_info_p.sym_l = (char *)s - s0;
553	return s_info_p;
554}
555
556static Sym *sysv_lookup(struct verinfo *verinfo,  struct sym_info_pair s_info_p, struct dso *dso)
557{
558	size_t i;
559	uint32_t h = s_info_p.sym_h;
560	Sym *syms = dso->syms;
561	Elf_Symndx *hashtab = dso->hashtab;
562	char *strings = dso->strings;
563	for (i=hashtab[2+h%hashtab[0]]; i; i=hashtab[2+hashtab[0]+i]) {
564		if ((!dso->versym || (dso->versym[i] & 0x7fff) >= 0)
565			&& (!memcmp(verinfo->s, strings+syms[i].st_name, s_info_p.sym_l))) {
566			if (!check_verinfo(dso->verdef, dso->versym, i, verinfo, dso->strings)) {
567				continue;
568			}
569
570			return syms+i;
571		}
572
573	}
574	LD_LOGD("sysv_lookup not find the symbol, "
575		"so:%{public}s s:%{public}s v:%{public}s use_vna_hash:%{public}d vna_hash:%{public}x",
576		dso->name, verinfo->s, verinfo->v, verinfo->use_vna_hash, verinfo->vna_hash);
577	return 0;
578}
579
580static Sym *gnu_lookup(struct sym_info_pair s_info_p, uint32_t *hashtab, struct dso *dso, struct verinfo *verinfo)
581{
582	uint32_t h1 = s_info_p.sym_h;
583	uint32_t nbuckets = hashtab[0];
584	uint32_t *buckets = hashtab + 4 + hashtab[2]*(sizeof(size_t)/4);
585	uint32_t i = buckets[h1 % nbuckets];
586
587	if (!i) {
588		LD_LOGD("gnu_lookup symbol not found (bloom filter), so:%{public}s s:%{public}s", dso->name, verinfo->s);
589		return 0;
590	}
591
592	uint32_t *hashval = buckets + nbuckets + (i - hashtab[1]);
593
594	for (h1 |= 1; ; i++) {
595		uint32_t h2 = *hashval++;
596		if ((h1 == (h2|1)) && (!dso->versym || (dso->versym[i] & 0x7fff) >= 0)
597			&& !memcmp(verinfo->s, dso->strings + dso->syms[i].st_name, s_info_p.sym_l)) {
598			if (!check_verinfo(dso->verdef, dso->versym, i, verinfo, dso->strings)) {
599				continue;
600			}
601
602			return dso->syms+i;
603		}
604
605		if (h2 & 1) break;
606	}
607
608	LD_LOGD("gnu_lookup symbol not found, "
609		"so:%{public}s s:%{public}s v:%{public}s use_vna_hash:%{public}d vna_hash:%{public}x",
610		dso->name, verinfo->s, verinfo->v, verinfo->use_vna_hash, verinfo->vna_hash);
611	return 0;
612}
613
614static bool check_sym_accessible(struct dso *dso, ns_t *ns)
615{
616	if (!dso || !dso->namespace || !ns) {
617		LD_LOGD("check_sym_accessible invalid parameter!");
618		return false;
619	}
620	if (dso->namespace == ns) {
621		return true;
622	}
623	for (int i = 0; i < dso->parents_count; i++) {
624		if (dso->parents[i]->namespace == ns) {
625			return true;
626		}
627	}
628	LD_LOGD(
629		"check_sym_accessible dso name [%{public}s] ns_name [%{public}s] not accessible!", dso->name, ns->ns_name);
630	return false;
631}
632
633static inline bool is_dso_accessible(struct dso *dso, ns_t *ns)
634{
635	if (dso->namespace == ns) {
636		return true;
637	}
638	for (int i = 0; i < dso->parents_count; i++) {
639		if (dso->parents[i]->namespace == ns) {
640			return true;
641		}
642	}
643	LD_LOGD(
644		"check_sym_accessible dso name [%{public}s] ns_name [%{public}s] not accessible!", dso->name, ns->ns_name);
645	return false;
646}
647
648static int find_dso_parent(struct dso *p, struct dso *target)
649{
650	int index = -1;
651	for (int i = 0; i < p->parents_count; i++) {
652		if (p->parents[i] == target) {
653			index = i;
654			break;
655		}
656	}
657	return index;
658}
659
660static void add_dso_parent(struct dso *p, struct dso *parent)
661{
662	int index = find_dso_parent(p, parent);
663	if (index != -1) {
664		return;
665	}
666	if (p->parents_count + 1 > p->parents_capacity) {
667		if (p->parents_capacity == 0) {
668			p->parents = (struct dso **)malloc(sizeof(struct dso *) * PARENTS_BASE_CAPACITY);
669			if (!p->parents) {
670				return;
671			}
672			p->parents_capacity = PARENTS_BASE_CAPACITY;
673		} else {
674			struct dso ** realloced = (struct dso **)realloc(
675				p->parents, sizeof(struct dso *) * (p->parents_capacity + PARENTS_BASE_CAPACITY));
676			if (!realloced) {
677				return;
678			}
679			p->parents = realloced;
680			p->parents_capacity += PARENTS_BASE_CAPACITY;
681		}
682	}
683	p->parents[p->parents_count] = parent;
684	p->parents_count++;
685}
686
687static void remove_dso_parent(struct dso *p, struct dso *parent)
688{
689	int index = find_dso_parent(p, parent);
690	if (index == -1) {
691		return;
692	}
693	int i;
694	for (i = 0; i < index; i++) {
695		p->parents[i] = p->parents[i];
696	}
697	for (i = index; i < p->parents_count - 1; i++) {
698		p->parents[i] = p->parents[i + 1];
699	}
700	p->parents_count--;
701}
702
703static void add_reloc_can_search_dso(struct dso *p, struct dso *can_search_so)
704{
705	if (p->reloc_can_search_dso_count + 1 > p->reloc_can_search_dso_capacity) {
706		if (p->reloc_can_search_dso_capacity == 0) {
707			p->reloc_can_search_dso_list =
708				(struct dso **)malloc(sizeof(struct dso *) * RELOC_CAN_SEARCH_DSO_BASE_CAPACITY);
709			if (!p->reloc_can_search_dso_list) {
710				return;
711			}
712			p->reloc_can_search_dso_capacity = RELOC_CAN_SEARCH_DSO_BASE_CAPACITY;
713		} else {
714			struct dso ** realloced = (struct dso **)realloc(
715				p->reloc_can_search_dso_list,
716				sizeof(struct dso *) * (p->reloc_can_search_dso_capacity + RELOC_CAN_SEARCH_DSO_BASE_CAPACITY));
717			if (!realloced) {
718				return;
719			}
720			p->reloc_can_search_dso_list = realloced;
721			p->reloc_can_search_dso_capacity += RELOC_CAN_SEARCH_DSO_BASE_CAPACITY;
722		}
723	}
724	p->reloc_can_search_dso_list[p->reloc_can_search_dso_count] = can_search_so;
725	p->reloc_can_search_dso_count++;
726}
727
728static void free_reloc_can_search_dso(struct dso *p)
729{
730	if (p->reloc_can_search_dso_list) {
731		free(p->reloc_can_search_dso_list);
732		p->reloc_can_search_dso_list = NULL;
733		p->reloc_can_search_dso_count = 0;
734		p->reloc_can_search_dso_capacity = 0;
735	}
736}
737
738/* The list of so that can be accessed during relocation include:
739 * - The is_global flag of the so is true which means accessible by default.
740 *   Global so includes exe, ld preload so and ldso.
741 * - We only check whether ns is accessible for the so if is_reloc_head_so_dep is true.
742 *
743 *   How to set is_reloc_head_so_dep:
744 *   When dlopen A, we set is_reloc_head_so_dep to true for
745 *   all direct and indirect dependent sos of A, including A itself. */
746static void add_can_search_so_list_in_dso(struct dso *dso_relocating, struct dso *start_check_dso) {
747	struct dso *p = start_check_dso;
748	for (; p; p = p->syms_next) {
749		if (p->is_global) {
750			add_reloc_can_search_dso(dso_relocating, p);
751			continue;
752		}
753
754		if (p->is_reloc_head_so_dep) {
755			if (dso_relocating->namespace && check_sym_accessible(p, dso_relocating->namespace)) {
756				add_reloc_can_search_dso(dso_relocating, p);
757			}
758		}
759	}
760
761	return;
762}
763
764#define OK_TYPES (1<<STT_NOTYPE | 1<<STT_OBJECT | 1<<STT_FUNC | 1<<STT_COMMON | 1<<STT_TLS)
765#define OK_BINDS (1<<STB_GLOBAL | 1<<STB_WEAK | 1<<STB_GNU_UNIQUE)
766
767#ifndef ARCH_SYM_REJECT_UND
768#define ARCH_SYM_REJECT_UND(s) 0
769#endif
770
771#if defined(__GNUC__)
772__attribute__((always_inline))
773#endif
774
775struct symdef find_sym_impl(
776	struct dso *dso, struct verinfo *verinfo, struct sym_info_pair s_info_g, int need_def, ns_t *ns)
777{
778	Sym *sym;
779	struct sym_info_pair s_info_s = {0, 0};
780	uint32_t *ght;
781	uint32_t gh = s_info_g.sym_h;
782	uint32_t gho = gh / (8 * sizeof(size_t));
783	size_t ghm = 1ul << gh % (8 * sizeof(size_t));
784	struct symdef def = {0};
785	if (ns && !check_sym_accessible(dso, ns))
786		return def;
787
788	if ((ght = dso->ghashtab)) {
789		const size_t *bloomwords = (const void *)(ght + 4);
790		size_t f = bloomwords[gho & (ght[2] - 1)];
791		if (!(f & ghm))
792			return def;
793
794		f >>= (gh >> ght[3]) % (8 * sizeof f);
795		if (!(f & 1))
796			return def;
797
798		sym = gnu_lookup(s_info_g, ght, dso, verinfo);
799	} else {
800		if (!s_info_s.sym_h)
801			s_info_s = sysv_hash(verinfo->s);
802
803		sym = sysv_lookup(verinfo, s_info_s, dso);
804	}
805
806	if (!sym)
807		return def;
808
809	if (!sym->st_shndx)
810		if (need_def || (sym->st_info & 0xf) == STT_TLS || ARCH_SYM_REJECT_UND(sym))
811			return def;
812
813	if (!sym->st_value)
814		if ((sym->st_info & 0xf) != STT_TLS)
815			return def;
816
817	if (!(1 << (sym->st_info & 0xf) & OK_TYPES))
818		return def;
819
820	if (!(1 << (sym->st_info >> 4) & OK_BINDS))
821		return def;
822
823	def.sym = sym;
824	def.dso = dso;
825	return def;
826}
827
828static inline struct symdef find_sym2(struct dso *dso, struct verinfo *verinfo, int need_def, int use_deps, ns_t *ns)
829{
830	struct sym_info_pair s_info_g = gnu_hash(verinfo->s);
831	struct sym_info_pair s_info_s = {0, 0};
832	uint32_t gh = s_info_g.sym_h, gho = gh / (8*sizeof(size_t)), *ght;
833	size_t ghm = 1ul << gh % (8*sizeof(size_t));
834	struct symdef def = {0};
835	struct dso **deps = use_deps ? dso->deps : 0;
836	for (; dso; dso=use_deps ? *deps++ : dso->syms_next) {
837		Sym *sym;
838		if (ns && !check_sym_accessible(dso, ns)) {
839			continue;
840		}
841		if ((ght = dso->ghashtab)) {
842			GNU_HASH_FILTER(ght, ghm, gho)
843			sym = gnu_lookup(s_info_g, ght, dso, verinfo);
844		} else {
845			if (!s_info_s.sym_h) s_info_s = sysv_hash(verinfo->s);
846			sym = sysv_lookup(verinfo, s_info_s, dso);
847		}
848
849		if (!sym) continue;
850		if (!sym->st_shndx)
851			if (need_def || (sym->st_info&0xf) == STT_TLS
852				|| ARCH_SYM_REJECT_UND(sym))
853				continue;
854		if (!sym->st_value)
855			if ((sym->st_info&0xf) != STT_TLS)
856				continue;
857		if (!(1<<(sym->st_info&0xf) & OK_TYPES)) continue;
858		if (!(1<<(sym->st_info>>4) & OK_BINDS)) continue;
859		def.sym = sym;
860		def.dso = dso;
861		break;
862	}
863	return def;
864}
865
866static inline struct symdef find_sym_by_deps(struct dso *dso, struct verinfo *verinfo, int need_def, ns_t *ns)
867{
868	struct sym_info_pair s_info_g = gnu_hash(verinfo->s);
869	struct sym_info_pair s_info_s = {0, 0};
870	uint32_t h = 0, gh = s_info_g.sym_h, gho = gh / (8*sizeof(size_t)), *ght;
871	size_t ghm = 1ul << gh % (8*sizeof(size_t));
872	struct symdef def = {0};
873	struct dso **deps = dso->deps;
874	for (; dso; dso=*deps++) {
875		Sym *sym;
876		if (!is_dso_accessible(dso, ns)) {
877			continue;
878		}
879		if ((ght = dso->ghashtab)) {
880			GNU_HASH_FILTER(ght, ghm, gho)
881			sym = gnu_lookup(s_info_g, ght, dso, verinfo);
882		} else {
883			if (!s_info_s.sym_h) s_info_s = sysv_hash(verinfo->s);
884			sym = sysv_lookup(verinfo, s_info_s, dso);
885		}
886
887		if (!sym) continue;
888		if (!sym->st_shndx)
889			if (need_def || (sym->st_info&0xf) == STT_TLS
890				|| ARCH_SYM_REJECT_UND(sym))
891				continue;
892		if (!sym->st_value)
893			if ((sym->st_info&0xf) != STT_TLS)
894				continue;
895		if (!(1<<(sym->st_info&0xf) & OK_TYPES)) continue;
896		if (!(1<<(sym->st_info>>4) & OK_BINDS)) continue;
897		def.sym = sym;
898		def.dso = dso;
899		break;
900	}
901	return def;
902}
903
904static inline struct symdef find_sym_by_saved_so_list(
905	int sym_type, struct dso *dso, struct verinfo *verinfo, int need_def, struct dso *dso_relocating)
906{
907	struct sym_info_pair s_info_g = gnu_hash(verinfo->s);
908	struct sym_info_pair s_info_s = {0, 0};
909	uint32_t gh = s_info_g.sym_h, gho = gh / (8 * sizeof(size_t)), *ght;
910	size_t ghm = 1ul << gh % (8 * sizeof(size_t));
911	struct symdef def = {0};
912	// skip head dso.
913	int start_search_index = sym_type==REL_COPY ? 1 : 0;
914	struct dso *dso_searching = 0;
915	for (int i = start_search_index; i < dso_relocating->reloc_can_search_dso_count; i++) {
916		dso_searching = dso_relocating->reloc_can_search_dso_list[i];
917		Sym *sym;
918		if ((ght = dso_searching->ghashtab)) {
919			GNU_HASH_FILTER(ght, ghm, gho)
920			sym = gnu_lookup(s_info_g, ght, dso_searching, verinfo);
921		} else {
922			if (!s_info_s.sym_h) s_info_s = sysv_hash(verinfo->s);
923			sym = sysv_lookup(verinfo, s_info_s, dso_searching);
924		}
925		if (!sym) continue;
926		if (!sym->st_shndx)
927			if (need_def || (sym->st_info&0xf) == STT_TLS
928				|| ARCH_SYM_REJECT_UND(sym))
929				continue;
930		if (!sym->st_value)
931			if ((sym->st_info&0xf) != STT_TLS)
932				continue;
933		if (!(1<<(sym->st_info&0xf) & OK_TYPES)) continue;
934		if (!(1<<(sym->st_info>>4) & OK_BINDS)) continue;
935		def.sym = sym;
936		def.dso = dso_searching;
937		break;
938	}
939	return def;
940}
941
942static struct symdef find_sym(struct dso *dso, const char *s, int need_def)
943{
944	struct verinfo verinfo = { .s = s, .v = "", .use_vna_hash = false };
945	return find_sym2(dso, &verinfo, need_def, 0, NULL);
946}
947
948static bool get_vna_hash(struct dso *dso, int sym_index, uint32_t *vna_hash)
949{
950	if (!dso->versym || !dso->verneed) {
951		return false;
952	}
953
954	uint16_t vsym = dso->versym[sym_index];
955	if (vsym == VER_NDX_LOCAL || vsym == VER_NDX_GLOBAL) {
956		return false;
957	}
958
959	bool result = false;
960	Verneed *verneed = dso->verneed;
961	Vernaux *vernaux;
962	vsym &= 0x7fff;
963
964	for(;;) {
965		vernaux = (Vernaux *)((char *)verneed + verneed->vn_aux);
966
967		for (size_t cnt = 0; cnt < verneed->vn_cnt; cnt++) {
968			if ((vernaux->vna_other & 0x7fff) == vsym) {
969				result = true;
970				*vna_hash = vernaux->vna_hash;
971				break;
972			}
973
974			vernaux = (Vernaux *)((char *)vernaux + vernaux->vna_next);
975		}
976
977		if (result) {
978			break;
979		}
980
981		if (verneed->vn_next == 0) {
982			break;
983		}
984
985		verneed = (Verneed *)((char *)verneed + verneed->vn_next);
986	}
987	return result;
988}
989
990static void get_verinfo(struct dso *dso, int sym_index, struct verinfo *vinfo)
991{
992	char *strings = dso->strings;
993	// try to get version number from .gnu.version
994	int16_t vsym = dso->versym[sym_index];
995	Verdef *verdef = dso->verdef;
996	vsym &= 0x7fff;
997	if (!verdef) {
998		return;
999	}
1000	int version_found = 0;
1001	for (;;) {
1002		if (!verdef) {
1003			break;
1004		}
1005		if (!(verdef->vd_flags & VER_FLG_BASE) && (verdef->vd_ndx & 0x7fff) == vsym) {
1006			version_found = 1;
1007			break;
1008		}
1009		if (verdef->vd_next == 0) {
1010			break;
1011		}
1012		verdef = (Verdef *)((char *)verdef + verdef->vd_next);
1013	}
1014	if (version_found) {
1015		Verdaux *aux = (Verdaux *)((char *)verdef + verdef->vd_aux);
1016		if (aux && aux->vda_name && strings && (dso->strings + aux->vda_name)) {
1017			vinfo->v = dso->strings + aux->vda_name;
1018		}
1019	}
1020}
1021
1022static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stride)
1023{
1024	unsigned char *base = dso->base;
1025	Sym *syms = dso->syms;
1026	char *strings = dso->strings;
1027	Sym *sym;
1028	const char *name;
1029	void *ctx;
1030	int type;
1031	int sym_index;
1032	struct symdef def;
1033	size_t *reloc_addr;
1034	size_t sym_val;
1035	size_t tls_val;
1036	size_t addend;
1037	int skip_relative = 0, reuse_addends = 0, save_slot = 0;
1038
1039	if (dso == &ldso) {
1040		/* Only ldso's REL table needs addend saving/reuse. */
1041		if (rel == apply_addends_to)
1042			reuse_addends = 1;
1043		skip_relative = 1;
1044	}
1045
1046	for (; rel_size; rel+=stride, rel_size-=stride*sizeof(size_t)) {
1047		if (skip_relative && IS_RELATIVE(rel[1], dso->syms)) continue;
1048		type = R_TYPE(rel[1]);
1049		if (type == REL_NONE) continue;
1050		reloc_addr = laddr(dso, rel[0]);
1051
1052		if (stride > 2) {
1053			addend = rel[2];
1054		} else if (type==REL_GOT || type==REL_PLT|| type==REL_COPY) {
1055			addend = 0;
1056		} else if (reuse_addends) {
1057			/* Save original addend in stage 2 where the dso
1058			 * chain consists of just ldso; otherwise read back
1059			 * saved addend since the inline one was clobbered. */
1060			if (head==&ldso)
1061				saved_addends[save_slot] = *reloc_addr;
1062			addend = saved_addends[save_slot++];
1063		} else {
1064			addend = *reloc_addr;
1065		}
1066
1067		sym_index = R_SYM(rel[1]);
1068		if (sym_index) {
1069			sym = syms + sym_index;
1070			name = strings + sym->st_name;
1071			ctx = type==REL_COPY ? head->syms_next : head;
1072			struct verinfo vinfo = { .s = name, .v = ""};
1073
1074			vinfo.use_vna_hash = get_vna_hash(dso, sym_index, &vinfo.vna_hash);
1075			if (!vinfo.use_vna_hash && dso->versym && (dso->versym[sym_index] & 0x7fff) >= 0) {
1076				get_verinfo(dso, sym_index, &vinfo);
1077			}
1078			if (dso->cache_sym_index == sym_index) {
1079				def = (struct symdef){ .dso = dso->cache_dso, .sym = dso->cache_sym };
1080			} else {
1081				def = (sym->st_info>>4) == STB_LOCAL
1082					? (struct symdef){ .dso = dso, .sym = sym }
1083					: dso != &ldso ? find_sym_by_saved_so_list(type, ctx, &vinfo, type==REL_PLT, dso)
1084					: find_sym2(ctx, &vinfo, type==REL_PLT, 0, dso->namespace);
1085				dso->cache_sym_index = sym_index;
1086				dso->cache_dso = def.dso;
1087				dso->cache_sym = def.sym;
1088			}
1089
1090			if (!def.sym && (sym->st_shndx != SHN_UNDEF
1091				|| sym->st_info>>4 != STB_WEAK)) {
1092				if (dso->lazy && (type==REL_PLT || type==REL_GOT)) {
1093					dso->lazy[3*dso->lazy_cnt+0] = rel[0];
1094					dso->lazy[3*dso->lazy_cnt+1] = rel[1];
1095					dso->lazy[3*dso->lazy_cnt+2] = addend;
1096					dso->lazy_cnt++;
1097					continue;
1098				}
1099				LD_LOGE("relocating failed: symbol not found. "
1100					"dso=%{public}s s=%{public}s use_vna_hash=%{public}d van_hash=%{public}x",
1101					dso->name, name, vinfo.use_vna_hash, vinfo.vna_hash);
1102				error("Error relocating %s: %s: symbol not found",
1103					dso->name, name);
1104				if (runtime) longjmp(*rtld_fail, 1);
1105				continue;
1106			}
1107		} else {
1108			sym = 0;
1109			def.sym = 0;
1110			def.dso = dso;
1111		}
1112
1113		sym_val = def.sym ? (size_t)laddr(def.dso, def.sym->st_value) : 0;
1114		tls_val = def.sym ? def.sym->st_value : 0;
1115
1116		if ((type == REL_TPOFF || type == REL_TPOFF_NEG)
1117			&& def.dso->tls_id > static_tls_cnt) {
1118			error("Error relocating %s: %s: initial-exec TLS "
1119				"resolves to dynamic definition in %s",
1120				dso->name, name, def.dso->name);
1121			longjmp(*rtld_fail, 1);
1122		}
1123
1124		switch(type) {
1125		case REL_OFFSET:
1126			addend -= (size_t)reloc_addr;
1127		case REL_SYMBOLIC:
1128		case REL_GOT:
1129		case REL_PLT:
1130			*reloc_addr = sym_val + addend;
1131			break;
1132		case REL_USYMBOLIC:
1133			memcpy(reloc_addr, &(size_t){sym_val + addend}, sizeof(size_t));
1134			break;
1135		case REL_RELATIVE:
1136			*reloc_addr = (size_t)base + addend;
1137			break;
1138		case REL_SYM_OR_REL:
1139			if (sym) *reloc_addr = sym_val + addend;
1140			else *reloc_addr = (size_t)base + addend;
1141			break;
1142		case REL_COPY:
1143			memcpy(reloc_addr, (void *)sym_val, sym->st_size);
1144			break;
1145		case REL_OFFSET32:
1146			*(uint32_t *)reloc_addr = sym_val + addend
1147				- (size_t)reloc_addr;
1148			break;
1149		case REL_FUNCDESC:
1150			*reloc_addr = def.sym ? (size_t)(def.dso->funcdescs
1151				+ (def.sym - def.dso->syms)) : 0;
1152			break;
1153		case REL_FUNCDESC_VAL:
1154			if ((sym->st_info&0xf) == STT_SECTION) *reloc_addr += sym_val;
1155			else *reloc_addr = sym_val;
1156			reloc_addr[1] = def.sym ? (size_t)def.dso->got : 0;
1157			break;
1158		case REL_DTPMOD:
1159			*reloc_addr = def.dso->tls_id;
1160			break;
1161		case REL_DTPOFF:
1162			*reloc_addr = tls_val + addend - DTP_OFFSET;
1163			break;
1164#ifdef TLS_ABOVE_TP
1165		case REL_TPOFF:
1166			*reloc_addr = tls_val + def.dso->tls.offset + TPOFF_K + addend;
1167			break;
1168#else
1169		case REL_TPOFF:
1170			*reloc_addr = tls_val - def.dso->tls.offset + addend;
1171			break;
1172		case REL_TPOFF_NEG:
1173			*reloc_addr = def.dso->tls.offset - tls_val + addend;
1174			break;
1175#endif
1176		case REL_TLSDESC:
1177			if (stride<3) addend = reloc_addr[1];
1178			if (def.dso->tls_id > static_tls_cnt) {
1179				struct td_index *new = malloc(sizeof *new);
1180				if (!new) {
1181					error(
1182					"Error relocating %s: cannot allocate TLSDESC for %s",
1183					dso->name, sym ? name : "(local)" );
1184					longjmp(*rtld_fail, 1);
1185				}
1186				new->next = dso->td_index;
1187				dso->td_index = new;
1188				new->args[0] = def.dso->tls_id;
1189				new->args[1] = tls_val + addend - DTP_OFFSET;
1190				reloc_addr[0] = (size_t)__tlsdesc_dynamic;
1191				reloc_addr[1] = (size_t)new;
1192			} else {
1193				reloc_addr[0] = (size_t)__tlsdesc_static;
1194#ifdef TLS_ABOVE_TP
1195				reloc_addr[1] = tls_val + def.dso->tls.offset
1196					+ TPOFF_K + addend;
1197#else
1198				reloc_addr[1] = tls_val - def.dso->tls.offset
1199					+ addend;
1200#endif
1201			}
1202#ifdef TLSDESC_BACKWARDS
1203			/* Some archs (32-bit ARM at least) invert the order of
1204			 * the descriptor members. Fix them up here. */
1205			size_t tmp = reloc_addr[0];
1206			reloc_addr[0] = reloc_addr[1];
1207			reloc_addr[1] = tmp;
1208#endif
1209			break;
1210		default:
1211			error("Error relocating %s: unsupported relocation type %d",
1212				dso->name, type);
1213			if (runtime) longjmp(*rtld_fail, 1);
1214			continue;
1215		}
1216	}
1217}
1218
1219static void redo_lazy_relocs()
1220{
1221	struct dso *p = lazy_head, *next;
1222	lazy_head = 0;
1223	for (; p; p=next) {
1224		next = p->lazy_next;
1225		size_t size = p->lazy_cnt*3*sizeof(size_t);
1226		p->lazy_cnt = 0;
1227		do_relocs(p, p->lazy, size, 3);
1228		if (p->lazy_cnt) {
1229			p->lazy_next = lazy_head;
1230			lazy_head = p;
1231		} else {
1232			free(p->lazy);
1233			p->lazy = 0;
1234			p->lazy_next = 0;
1235		}
1236	}
1237}
1238
1239/* A huge hack: to make up for the wastefulness of shared libraries
1240 * needing at least a page of dirty memory even if they have no global
1241 * data, we reclaim the gaps at the beginning and end of writable maps
1242 * and "donate" them to the heap. */
1243
1244static void reclaim(struct dso *dso, size_t start, size_t end)
1245{
1246	if (start >= dso->relro_start && start < dso->relro_end) start = dso->relro_end;
1247	if (end   >= dso->relro_start && end   < dso->relro_end) end = dso->relro_start;
1248	if (start >= end) return;
1249	char *base = laddr_pg(dso, start);
1250	__malloc_donate(base, base+(end-start));
1251}
1252
1253static void reclaim_gaps(struct dso *dso)
1254{
1255	Phdr *ph = dso->phdr;
1256	size_t phcnt = dso->phnum;
1257
1258	for (; phcnt--; ph=(void *)((char *)ph+dso->phentsize)) {
1259		if (ph->p_type!=PT_LOAD) continue;
1260		if ((ph->p_flags&(PF_R|PF_W))!=(PF_R|PF_W)) continue;
1261		reclaim(dso, ph->p_vaddr & -PAGE_SIZE, ph->p_vaddr);
1262		reclaim(dso, ph->p_vaddr+ph->p_memsz,
1263			ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE);
1264	}
1265}
1266
1267static ssize_t read_loop(int fd, void *p, size_t n)
1268{
1269	for (size_t i=0; i<n; ) {
1270		ssize_t l = read(fd, (char *)p+i, n-i);
1271		if (l<0) {
1272			if (errno==EINTR) continue;
1273			else return -1;
1274		}
1275		if (l==0) return i;
1276		i += l;
1277	}
1278	return n;
1279}
1280
1281UT_STATIC void *mmap_fixed(void *p, size_t n, int prot, int flags, int fd, off_t off)
1282{
1283	static int no_map_fixed;
1284	char *q;
1285	if (!n) return p;
1286	if (!no_map_fixed) {
1287		q = mmap(p, n, prot, flags|MAP_FIXED, fd, off);
1288		if (!DL_NOMMU_SUPPORT || q != MAP_FAILED || errno != EINVAL)
1289			return q;
1290		no_map_fixed = 1;
1291	}
1292	/* Fallbacks for MAP_FIXED failure on NOMMU kernels. */
1293	if (flags & MAP_ANONYMOUS) {
1294		memset(p, 0, n);
1295		return p;
1296	}
1297	ssize_t r;
1298	if (lseek(fd, off, SEEK_SET) < 0) return MAP_FAILED;
1299	for (q=p; n; q+=r, off+=r, n-=r) {
1300		r = read(fd, q, n);
1301		if (r < 0 && errno != EINTR) return MAP_FAILED;
1302		if (!r) {
1303			memset(q, 0, n);
1304			break;
1305		}
1306	}
1307	return p;
1308}
1309
1310UT_STATIC void unmap_library(struct dso *dso)
1311{
1312	if (dso->loadmap) {
1313		size_t i;
1314		for (i=0; i<dso->loadmap->nsegs; i++) {
1315			if (!dso->loadmap->segs[i].p_memsz)
1316				continue;
1317			if (!is_dlclose_debug_enable()) {
1318				munmap((void *)dso->loadmap->segs[i].addr,
1319					dso->loadmap->segs[i].p_memsz);
1320			} else {
1321				(void)mprotect((void *)dso->loadmap->segs[i].addr,
1322					dso->loadmap->segs[i].p_memsz, PROT_NONE);
1323			}
1324		}
1325		free(dso->loadmap);
1326	} else if (dso->map && dso->map_len) {
1327		if (!is_dlclose_debug_enable()) {
1328			munmap(dso->map, dso->map_len);
1329		} else {
1330			mprotect(dso->map, dso->map_len, PROT_NONE);
1331		}
1332	}
1333}
1334
1335UT_STATIC bool get_random(void *buf, size_t buflen)
1336{
1337	int ret;
1338	int fd = open("/dev/urandom", O_RDONLY);
1339	if (fd < 0) {
1340		return false;
1341	}
1342
1343	ret = read(fd, buf, buflen);
1344	if (ret < 0) {
1345		close(fd);
1346		return false;
1347	}
1348
1349	close(fd);
1350	return true;
1351}
1352
1353UT_STATIC void fill_random_data(void *buf, size_t buflen)
1354{
1355	uint64_t x;
1356	int i;
1357	int pos = 0;
1358	struct timespec ts;
1359	/* Try to use urandom to get the random number first */
1360	if (!get_random(buf, buflen)) {
1361		/* Can't get random number from /dev/urandom, generate from addr based on ASLR and time */
1362		for (i = 1; i <= (buflen / sizeof(x)); i++) {
1363			(void)clock_gettime(CLOCK_REALTIME, &ts);
1364			x = (((uint64_t)get_random) << 32) ^ (uint64_t)fill_random_data ^ ts.tv_nsec;
1365			memcpy((char *)buf + pos, &x, sizeof(x));
1366			pos += sizeof(x);
1367		}
1368	}
1369	return;
1370}
1371
1372static bool get_transparent_hugepages_supported(void)
1373{
1374	int fd = -1;
1375	ssize_t read_size = 0;
1376	bool enable = false;
1377	char buf[HUGEPAGES_SUPPORTED_STR_SIZE] = {'0'};
1378
1379	fd = open("/sys/kernel/mm/transparent_hugepage/enabled", O_RDONLY);
1380	if (fd < 0)
1381		goto done;
1382
1383	read_size = read(fd, buf, HUGEPAGES_SUPPORTED_STR_SIZE - 1);
1384	if (read_size < 0)
1385		goto close_fd;
1386
1387	buf[HUGEPAGES_SUPPORTED_STR_SIZE - 1] = '\0';
1388	if (strstr(buf, "[never]") == NULL)
1389		enable = true;
1390
1391close_fd:
1392	close(fd);
1393done:
1394	return enable;
1395}
1396
1397static size_t phdr_table_get_maxinum_alignment(Phdr *phdr_table, size_t phdr_count)
1398{
1399#if defined(__LP64__)
1400	size_t maxinum_alignment = PAGE_SIZE;
1401	size_t i = 0;
1402
1403	for (i = 0; i < phdr_count; ++i) {
1404		const Phdr *phdr = &phdr_table[i];
1405
1406		/* p_align must be 0, 1, or a positive, integral power of two */
1407		if ((phdr->p_type != PT_LOAD) || ((phdr->p_align & (phdr->p_align - 1)) != 0))
1408			continue;
1409
1410		if (phdr->p_align > maxinum_alignment)
1411			maxinum_alignment = phdr->p_align;
1412	}
1413
1414	return maxinum_alignment;
1415#else
1416	return PAGE_SIZE;
1417#endif
1418}
1419
1420UT_STATIC void *map_library(int fd, struct dso *dso, struct reserved_address_params *reserved_params)
1421{
1422	Ehdr buf[(896+sizeof(Ehdr))/sizeof(Ehdr)];
1423	void *allocated_buf=0;
1424	size_t phsize;
1425	size_t addr_min=SIZE_MAX, addr_max=0, map_len;
1426	size_t this_min, this_max;
1427	size_t nsegs = 0;
1428	off_t off_start;
1429	Ehdr *eh;
1430	Phdr *ph, *ph0;
1431	unsigned prot;
1432	unsigned char *map=MAP_FAILED, *base;
1433	size_t dyn=0;
1434	size_t tls_image=0;
1435	size_t i;
1436	int map_flags = MAP_PRIVATE;
1437	size_t start_addr;
1438	size_t start_alignment = PAGE_SIZE;
1439	bool hugepage_enabled = false;
1440
1441	ssize_t l = read(fd, buf, sizeof buf);
1442	eh = buf;
1443	if (l<0) return 0;
1444	if (l<sizeof *eh || (eh->e_type != ET_DYN && eh->e_type != ET_EXEC))
1445		goto noexec;
1446	phsize = eh->e_phentsize * eh->e_phnum;
1447	if (phsize > sizeof buf - sizeof *eh) {
1448		allocated_buf = malloc(phsize);
1449		if (!allocated_buf) return 0;
1450		l = pread(fd, allocated_buf, phsize, eh->e_phoff);
1451		if (l < 0) goto error;
1452		if (l != phsize) goto noexec;
1453		ph = ph0 = allocated_buf;
1454	} else if (eh->e_phoff + phsize > l) {
1455		l = pread(fd, buf+1, phsize, eh->e_phoff);
1456		if (l < 0) goto error;
1457		if (l != phsize) goto noexec;
1458		ph = ph0 = (void *)(buf + 1);
1459	} else {
1460		ph = ph0 = (void *)((char *)buf + eh->e_phoff);
1461	}
1462	for (i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) {
1463		if (ph->p_type == PT_DYNAMIC) {
1464			dyn = ph->p_vaddr;
1465		} else if (ph->p_type == PT_TLS) {
1466			tls_image = ph->p_vaddr;
1467			dso->tls.align = ph->p_align;
1468			dso->tls.len = ph->p_filesz;
1469			dso->tls.size = ph->p_memsz;
1470		} else if (ph->p_type == PT_GNU_RELRO) {
1471			dso->relro_start = ph->p_vaddr & -PAGE_SIZE;
1472			dso->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE;
1473		} else if (ph->p_type == PT_GNU_STACK) {
1474			if (!runtime && ph->p_memsz > __default_stacksize) {
1475				__default_stacksize =
1476					ph->p_memsz < DEFAULT_STACK_MAX ?
1477					ph->p_memsz : DEFAULT_STACK_MAX;
1478			}
1479		}
1480		if (ph->p_type != PT_LOAD) continue;
1481		nsegs++;
1482		if (ph->p_vaddr < addr_min) {
1483			addr_min = ph->p_vaddr;
1484			off_start = ph->p_offset;
1485			prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |
1486				((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
1487				((ph->p_flags&PF_X) ? PROT_EXEC : 0));
1488		}
1489		if (ph->p_vaddr+ph->p_memsz > addr_max) {
1490			addr_max = ph->p_vaddr+ph->p_memsz;
1491		}
1492	}
1493	if (!dyn) goto noexec;
1494	if (DL_FDPIC && !(eh->e_flags & FDPIC_CONSTDISP_FLAG)) {
1495		dso->loadmap = calloc(1, sizeof *dso->loadmap
1496			+ nsegs * sizeof *dso->loadmap->segs);
1497		if (!dso->loadmap) goto error;
1498		dso->loadmap->nsegs = nsegs;
1499		for (ph=ph0, i=0; i<nsegs; ph=(void *)((char *)ph+eh->e_phentsize)) {
1500			if (ph->p_type != PT_LOAD) continue;
1501			prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |
1502				((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
1503				((ph->p_flags&PF_X) ? PROT_EXEC : 0));
1504			map = mmap(0, ph->p_memsz + (ph->p_vaddr & PAGE_SIZE-1),
1505				prot, MAP_PRIVATE,
1506				fd, ph->p_offset & -PAGE_SIZE);
1507			if (map == MAP_FAILED) {
1508				unmap_library(dso);
1509				goto error;
1510			}
1511			dso->loadmap->segs[i].addr = (size_t)map +
1512				(ph->p_vaddr & PAGE_SIZE-1);
1513			dso->loadmap->segs[i].p_vaddr = ph->p_vaddr;
1514			dso->loadmap->segs[i].p_memsz = ph->p_memsz;
1515			i++;
1516			if (prot & PROT_WRITE) {
1517				size_t brk = (ph->p_vaddr & PAGE_SIZE-1)
1518					+ ph->p_filesz;
1519				size_t pgbrk = brk + PAGE_SIZE-1 & -PAGE_SIZE;
1520				size_t pgend = brk + ph->p_memsz - ph->p_filesz
1521					+ PAGE_SIZE-1 & -PAGE_SIZE;
1522				if (pgend > pgbrk && mmap_fixed(map+pgbrk,
1523					pgend-pgbrk, prot,
1524					MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS,
1525					-1, off_start) == MAP_FAILED)
1526					goto error;
1527				memset(map + brk, 0, pgbrk-brk);
1528			}
1529		}
1530		map = (void *)dso->loadmap->segs[0].addr;
1531		map_len = 0;
1532		goto done_mapping;
1533	}
1534	addr_max += PAGE_SIZE-1;
1535	addr_max &= -PAGE_SIZE;
1536	addr_min &= -PAGE_SIZE;
1537	off_start &= -PAGE_SIZE;
1538	map_len = addr_max - addr_min + off_start;
1539	start_addr = addr_min;
1540
1541	hugepage_enabled = get_transparent_hugepages_supported();
1542	if (hugepage_enabled) {
1543		size_t maxinum_alignment = phdr_table_get_maxinum_alignment(ph0, eh->e_phnum);
1544
1545		start_alignment = maxinum_alignment == KPMD_SIZE ? KPMD_SIZE : PAGE_SIZE;
1546	}
1547
1548	if (reserved_params) {
1549		if (map_len > reserved_params->reserved_size) {
1550			if (reserved_params->must_use_reserved) {
1551				goto error;
1552			}
1553		} else {
1554			start_addr = ((size_t)reserved_params->start_addr - 1 + PAGE_SIZE) & -PAGE_SIZE;
1555			map_flags |= MAP_FIXED;
1556		}
1557	}
1558
1559	/* we will find a mapping_align aligned address as the start of dso
1560	 * so we need a tmp_map_len as map_len + mapping_align to make sure
1561	 * we have enough space to shift the dso to the correct location. */
1562	size_t mapping_align = start_alignment > LIBRARY_ALIGNMENT ? start_alignment : LIBRARY_ALIGNMENT;
1563	size_t tmp_map_len = ALIGN(map_len, mapping_align) + mapping_align - PAGE_SIZE;
1564
1565	/* if reserved_params exists, we should use start_addr as prefered result to do the mmap operation */
1566	if (reserved_params) {
1567		map = DL_NOMMU_SUPPORT
1568			? mmap((void *)start_addr, map_len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)
1569			: mmap((void *)start_addr, map_len, prot, map_flags, fd, off_start);
1570		if (map == MAP_FAILED) {
1571			goto error;
1572		}
1573		if (reserved_params && map_len < reserved_params->reserved_size) {
1574			reserved_params->reserved_size -= (map_len + (start_addr - (size_t)reserved_params->start_addr));
1575			reserved_params->start_addr = (void *)((uint8_t *)map + map_len);
1576		}
1577	/* if reserved_params does not exist, we should use real_map as prefered result to do the mmap operation */
1578	} else {
1579		/* use tmp_map_len to mmap enough space for the dso with anonymous mapping */
1580		unsigned char *temp_map = mmap((void *)NULL, tmp_map_len, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
1581		if (temp_map == MAP_FAILED) {
1582			goto error;
1583		}
1584
1585		/* find the mapping_align aligned address */
1586		unsigned char *real_map = (unsigned char*)ALIGN((uintptr_t)temp_map, mapping_align);
1587
1588		/* mummap the space we mmap before so that we can mmap correct space again */
1589		munmap(temp_map, tmp_map_len);
1590
1591		map = DL_NOMMU_SUPPORT
1592			? mmap(real_map, map_len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)
1593			/* use map_len to mmap correct space for the dso with file mapping */
1594			: mmap(real_map, map_len, prot, map_flags, fd, off_start);
1595		if (map == MAP_FAILED) {
1596			goto error;
1597		}
1598	}
1599	dso->map = map;
1600	dso->map_len = map_len;
1601	/* If the loaded file is not relocatable and the requested address is
1602	 * not available, then the load operation must fail. */
1603	if (eh->e_type != ET_DYN && addr_min && map!=(void *)addr_min) {
1604		errno = EBUSY;
1605		goto error;
1606	}
1607	base = map - addr_min;
1608	dso->phdr = 0;
1609	dso->phnum = 0;
1610	for (ph=ph0, i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) {
1611		if (ph->p_type == PT_OHOS_RANDOMDATA) {
1612			fill_random_data((void *)(ph->p_vaddr + base), ph->p_memsz);
1613			continue;
1614		}
1615		if (ph->p_type != PT_LOAD) continue;
1616		/* Check if the programs headers are in this load segment, and
1617		 * if so, record the address for use by dl_iterate_phdr. */
1618		if (!dso->phdr && eh->e_phoff >= ph->p_offset
1619			&& eh->e_phoff+phsize <= ph->p_offset+ph->p_filesz) {
1620			dso->phdr = (void *)(base + ph->p_vaddr
1621				+ (eh->e_phoff-ph->p_offset));
1622			dso->phnum = eh->e_phnum;
1623			dso->phentsize = eh->e_phentsize;
1624		}
1625		this_min = ph->p_vaddr & -PAGE_SIZE;
1626		this_max = ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE;
1627		off_start = ph->p_offset & -PAGE_SIZE;
1628		prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |
1629			((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
1630			((ph->p_flags&PF_X) ? PROT_EXEC : 0));
1631		/* Reuse the existing mapping for the lowest-address LOAD */
1632		if ((ph->p_vaddr & -PAGE_SIZE) != addr_min || DL_NOMMU_SUPPORT)
1633			if (mmap_fixed(base+this_min, this_max-this_min, prot, MAP_PRIVATE|MAP_FIXED, fd, off_start) == MAP_FAILED)
1634				goto error;
1635		if ((ph->p_flags & PF_X) && (ph->p_align == KPMD_SIZE) && hugepage_enabled)
1636			madvise(base + this_min, this_max - this_min, MADV_HUGEPAGE);
1637		if (ph->p_memsz > ph->p_filesz && (ph->p_flags&PF_W)) {
1638			size_t brk = (size_t)base+ph->p_vaddr+ph->p_filesz;
1639			size_t pgbrk = brk+PAGE_SIZE-1 & -PAGE_SIZE;
1640			size_t zeromap_size = (size_t)base+this_max-pgbrk;
1641			memset((void *)brk, 0, pgbrk-brk & PAGE_SIZE-1);
1642			if (pgbrk-(size_t)base < this_max && mmap_fixed((void *)pgbrk, zeromap_size, prot, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) == MAP_FAILED)
1643				goto error;
1644			set_bss_vma_name(dso->name, (void *)pgbrk, zeromap_size);
1645		}
1646	}
1647	for (i=0; ((size_t *)(base+dyn))[i]; i+=2)
1648		if (((size_t *)(base+dyn))[i]==DT_TEXTREL) {
1649			if (mprotect(map, map_len, PROT_READ|PROT_WRITE|PROT_EXEC)
1650				&& errno != ENOSYS)
1651				goto error;
1652			break;
1653		}
1654done_mapping:
1655	dso->base = base;
1656	dso->dynv = laddr(dso, dyn);
1657	if (dso->tls.size) dso->tls.image = laddr(dso, tls_image);
1658	free(allocated_buf);
1659	return map;
1660noexec:
1661	errno = ENOEXEC;
1662error:
1663	if (map!=MAP_FAILED) unmap_library(dso);
1664	free(allocated_buf);
1665	return 0;
1666}
1667
1668static int path_open(const char *name, const char *s, char *buf, size_t buf_size)
1669{
1670	size_t l;
1671	int fd;
1672	for (;;) {
1673		s += strspn(s, ":\n");
1674		l = strcspn(s, ":\n");
1675		if (l-1 >= INT_MAX) return -1;
1676		if (snprintf(buf, buf_size, "%.*s/%s", (int)l, s, name) < buf_size) {
1677			if ((fd = open(buf, O_RDONLY|O_CLOEXEC))>=0) return fd;
1678			switch (errno) {
1679			case ENOENT:
1680			case ENOTDIR:
1681			case EACCES:
1682			case ENAMETOOLONG:
1683				break;
1684			default:
1685				/* Any negative value but -1 will inhibit
1686				 * futher path search. */
1687				return -2;
1688			}
1689		}
1690		s += l;
1691	}
1692}
1693
1694UT_STATIC int fixup_rpath(struct dso *p, char *buf, size_t buf_size)
1695{
1696	size_t n, l;
1697	const char *s, *t, *origin;
1698	char *d;
1699	if (p->rpath || !p->rpath_orig) return 0;
1700	if (!strchr(p->rpath_orig, '$')) {
1701		p->rpath = p->rpath_orig;
1702		return 0;
1703	}
1704	n = 0;
1705	s = p->rpath_orig;
1706	while ((t=strchr(s, '$'))) {
1707		if (strncmp(t, "$ORIGIN", 7) && strncmp(t, "${ORIGIN}", 9))
1708			return 0;
1709		s = t+1;
1710		n++;
1711	}
1712	if (n > SSIZE_MAX/PATH_MAX) return 0;
1713
1714	if (p->kernel_mapped) {
1715		/* $ORIGIN searches cannot be performed for the main program
1716		 * when it is suid/sgid/AT_SECURE. This is because the
1717		 * pathname is under the control of the caller of execve.
1718		 * For libraries, however, $ORIGIN can be processed safely
1719		 * since the library's pathname came from a trusted source
1720		 * (either system paths or a call to dlopen). */
1721		if (libc.secure)
1722			return 0;
1723		l = readlink("/proc/self/exe", buf, buf_size);
1724		if (l == -1) switch (errno) {
1725		case ENOENT:
1726		case ENOTDIR:
1727		case EACCES:
1728			break;
1729		default:
1730			return -1;
1731		}
1732		if (l >= buf_size)
1733			return 0;
1734		buf[l] = 0;
1735		origin = buf;
1736	} else {
1737		origin = p->name;
1738	}
1739	t = strrchr(origin, '/');
1740	if (t) {
1741		l = t-origin;
1742	} else {
1743		/* Normally p->name will always be an absolute or relative
1744		 * pathname containing at least one '/' character, but in the
1745		 * case where ldso was invoked as a command to execute a
1746		 * program in the working directory, app.name may not. Fix. */
1747		origin = ".";
1748		l = 1;
1749	}
1750	/* Disallow non-absolute origins for suid/sgid/AT_SECURE. */
1751	if (libc.secure && *origin != '/')
1752		return 0;
1753	p->rpath = malloc(strlen(p->rpath_orig) + n*l + 1);
1754	if (!p->rpath) return -1;
1755
1756	d = p->rpath;
1757	s = p->rpath_orig;
1758	while ((t=strchr(s, '$'))) {
1759		memcpy(d, s, t-s);
1760		d += t-s;
1761		memcpy(d, origin, l);
1762		d += l;
1763		/* It was determined previously that the '$' is followed
1764		 * either by "ORIGIN" or "{ORIGIN}". */
1765		s = t + 7 + 2*(t[1]=='{');
1766	}
1767	strcpy(d, s);
1768	return 0;
1769}
1770
1771static void decode_dyn(struct dso *p)
1772{
1773	size_t dyn[DYN_CNT];
1774	size_t flags1 = 0;
1775	decode_vec(p->dynv, dyn, DYN_CNT);
1776	search_vec(p->dynv, &flags1, DT_FLAGS_1);
1777	if (flags1 & DF_1_GLOBAL) {
1778		LD_LOGI("Add DF_1_GLOBAL for %{public}s", p->name);
1779		p->is_global = true;
1780	}
1781	if (flags1 & DF_1_NODELETE) {
1782		p->flags |= DSO_FLAGS_NODELETE;
1783	}
1784	p->syms = laddr(p, dyn[DT_SYMTAB]);
1785	p->strings = laddr(p, dyn[DT_STRTAB]);
1786	if (dyn[0]&(1<<DT_HASH))
1787		p->hashtab = laddr(p, dyn[DT_HASH]);
1788	if (dyn[0]&(1<<DT_RPATH))
1789		p->rpath_orig = p->strings + dyn[DT_RPATH];
1790	if (dyn[0]&(1<<DT_RUNPATH))
1791		p->rpath_orig = p->strings + dyn[DT_RUNPATH];
1792	if (dyn[0]&(1<<DT_PLTGOT))
1793		p->got = laddr(p, dyn[DT_PLTGOT]);
1794	if (search_vec(p->dynv, dyn, DT_GNU_HASH))
1795		p->ghashtab = laddr(p, *dyn);
1796	if (search_vec(p->dynv, dyn, DT_VERSYM))
1797		p->versym = laddr(p, *dyn);
1798	if (search_vec(p->dynv, dyn, DT_VERDEF))
1799		p->verdef = laddr(p, *dyn);
1800	if (search_vec(p->dynv, dyn, DT_VERNEED))
1801		p->verneed = laddr(p, *dyn);
1802}
1803
1804UT_STATIC size_t count_syms(struct dso *p)
1805{
1806	if (p->hashtab) return p->hashtab[1];
1807
1808	size_t nsym, i;
1809	uint32_t *buckets = p->ghashtab + 4 + (p->ghashtab[2]*sizeof(size_t)/4);
1810	uint32_t *hashval;
1811	for (i = nsym = 0; i < p->ghashtab[0]; i++) {
1812		if (buckets[i] > nsym)
1813			nsym = buckets[i];
1814	}
1815	if (nsym) {
1816		hashval = buckets + p->ghashtab[0] + (nsym - p->ghashtab[1]);
1817		do nsym++;
1818		while (!(*hashval++ & 1));
1819	}
1820	return nsym;
1821}
1822
1823static void *dl_mmap(size_t n)
1824{
1825	void *p;
1826	int prot = PROT_READ|PROT_WRITE, flags = MAP_ANONYMOUS|MAP_PRIVATE;
1827#ifdef SYS_mmap2
1828	p = (void *)__syscall(SYS_mmap2, 0, n, prot, flags, -1, 0);
1829#else
1830	p = (void *)__syscall(SYS_mmap, 0, n, prot, flags, -1, 0);
1831#endif
1832	return (unsigned long)p > -4096UL ? 0 : p;
1833}
1834
1835static void makefuncdescs(struct dso *p)
1836{
1837	static int self_done;
1838	size_t nsym = count_syms(p);
1839	size_t i, size = nsym * sizeof(*p->funcdescs);
1840
1841	if (!self_done) {
1842		p->funcdescs = dl_mmap(size);
1843		self_done = 1;
1844	} else {
1845		p->funcdescs = malloc(size);
1846	}
1847	if (!p->funcdescs) {
1848		if (!runtime) a_crash();
1849		error("Error allocating function descriptors for %s", p->name);
1850		longjmp(*rtld_fail, 1);
1851	}
1852	for (i=0; i<nsym; i++) {
1853		if ((p->syms[i].st_info&0xf)==STT_FUNC && p->syms[i].st_shndx) {
1854			p->funcdescs[i].addr = laddr(p, p->syms[i].st_value);
1855			p->funcdescs[i].got = p->got;
1856		} else {
1857			p->funcdescs[i].addr = 0;
1858			p->funcdescs[i].got = 0;
1859		}
1860	}
1861}
1862
1863static void get_sys_path(ns_configor *conf)
1864{
1865	LD_LOGD("get_sys_path g_is_asan:%{public}d", g_is_asan);
1866	/* Use ini file's system paths when Asan is not enabled */
1867	if (!g_is_asan) {
1868		sys_path = conf->get_sys_paths();
1869	} else {
1870		/* Use ini file's asan system paths when the Asan is enabled
1871		 * Merge two strings when both sys_paths and asan_sys_paths are valid */
1872		sys_path = conf->get_asan_sys_paths();
1873		char *sys_path_default = conf->get_sys_paths();
1874		if (!sys_path) {
1875			sys_path = sys_path_default;
1876		} else if (sys_path_default) {
1877			size_t newlen = strlen(sys_path) + strlen(sys_path_default) + 2;
1878			char *new_syspath = malloc(newlen);
1879			memset(new_syspath, 0, newlen);
1880			strcpy(new_syspath, sys_path);
1881			strcat(new_syspath, ":");
1882			strcat(new_syspath, sys_path_default);
1883			sys_path = new_syspath;
1884		}
1885	}
1886	if (!sys_path) sys_path = "/lib:/usr/local/lib:/usr/lib:/lib64";
1887	LD_LOGD("get_sys_path sys_path:%{public}s", sys_path);
1888}
1889
1890static struct dso *search_dso_by_name(const char *name, const ns_t *ns) {
1891	LD_LOGD("search_dso_by_name name:%{public}s, ns_name:%{public}s", name, ns ? ns->ns_name: "NULL");
1892	for (size_t i = 0; i < ns->ns_dsos->num; i++){
1893		struct dso *p = ns->ns_dsos->dsos[i];
1894		if (p->shortname && !strcmp(p->shortname, name)) {
1895			LD_LOGD("search_dso_by_name found name:%{public}s, ns_name:%{public}s", name, ns ? ns->ns_name: "NULL");
1896			return p;
1897		}
1898	}
1899	return NULL;
1900}
1901
1902static struct dso *search_dso_by_fstat(const struct stat *st, const ns_t *ns, uint64_t file_offset) {
1903	LD_LOGD("search_dso_by_fstat ns_name:%{public}s", ns ? ns->ns_name : "NULL");
1904	for (size_t i = 0; i < ns->ns_dsos->num; i++){
1905		struct dso *p = ns->ns_dsos->dsos[i];
1906		if (p->dev == st->st_dev && p->ino == st->st_ino && p->file_offset == file_offset) {
1907			LD_LOGD("search_dso_by_fstat found dev:%{public}lu, ino:%{public}lu, ns_name:%{public}s",
1908				st->st_dev, st->st_ino, ns ? ns->ns_name : "NULL");
1909			return p;
1910		}
1911	}
1912	return NULL;
1913}
1914
1915static inline int app_has_same_name_so(const char *so_name, const ns_t *ns)
1916{
1917   int fd = -1;
1918   /* Only check system app. */
1919   if (((ns->flag & LOCAL_NS_PREFERED) != 0) && ns->lib_paths) {
1920       char tmp_buf[PATH_MAX+1];
1921       fd = path_open(so_name, ns->lib_paths, tmp_buf, sizeof tmp_buf);
1922   }
1923   return fd;
1924}
1925
1926/* Find loaded so by name */
1927static struct dso *find_library_by_name(const char *name, const ns_t *ns, bool check_inherited)
1928{
1929	LD_LOGD("find_library_by_name name:%{public}s, ns_name:%{public}s, check_inherited:%{public}d",
1930		name,
1931		ns ? ns->ns_name : "NULL",
1932		!!check_inherited);
1933	struct dso *p = search_dso_by_name(name, ns);
1934	if (p) return p;
1935	if (check_inherited && ns->ns_inherits) {
1936		for (size_t i = 0; i < ns->ns_inherits->num; i++){
1937			ns_inherit * inherit = ns->ns_inherits->inherits[i];
1938			p = search_dso_by_name(name, inherit->inherited_ns);
1939			if (p && is_sharable(inherit, name)) {
1940			    if (app_has_same_name_so(name, ns) != -1) {
1941			        return NULL;
1942			    }
1943			    return p;
1944			}
1945		}
1946	}
1947	return NULL;
1948}
1949/* Find loaded so by file stat */
1950UT_STATIC struct dso *find_library_by_fstat(const struct stat *st, const ns_t *ns, bool check_inherited, uint64_t file_offset) {
1951	LD_LOGD("find_library_by_fstat ns_name:%{public}s, check_inherited :%{public}d",
1952		ns ? ns->ns_name : "NULL",
1953		!!check_inherited);
1954	struct dso *p = search_dso_by_fstat(st, ns, file_offset);
1955	if (p) return p;
1956	if (check_inherited && ns->ns_inherits) {
1957		for (size_t i = 0; i < ns->ns_inherits->num; i++){
1958			ns_inherit *inherit = ns->ns_inherits->inherits[i];
1959			p = search_dso_by_fstat(st, inherit->inherited_ns, file_offset);
1960			if (p && is_sharable(inherit, p->shortname)) return p;
1961		}
1962	}
1963	return NULL;
1964}
1965
1966#ifndef LOAD_ORDER_RANDOMIZATION
1967/* add namespace function */
1968struct dso *load_library(
1969	const char *name, struct dso *needed_by, ns_t *namespace, bool check_inherited, struct reserved_address_params *reserved_params)
1970{
1971	char buf[PATH_MAX+1];
1972	const char *pathname;
1973	unsigned char *map;
1974	struct dso *p, temp_dso = {0};
1975	int fd;
1976	struct stat st;
1977	size_t alloc_size;
1978	int n_th = 0;
1979	int is_self = 0;
1980
1981	if (!*name) {
1982		errno = EINVAL;
1983		return 0;
1984	}
1985
1986	/* Catch and block attempts to reload the implementation itself */
1987	if (name[0]=='l' && name[1]=='i' && name[2]=='b') {
1988		static const char reserved[] =
1989			"c.pthread.rt.m.dl.util.xnet.";
1990		const char *rp, *next;
1991		for (rp=reserved; *rp; rp=next) {
1992			next = strchr(rp, '.') + 1;
1993			if (strncmp(name+3, rp, next-rp) == 0)
1994				break;
1995		}
1996		if (*rp) {
1997			if (ldd_mode) {
1998				/* Track which names have been resolved
1999				 * and only report each one once. */
2000				static unsigned reported;
2001				unsigned mask = 1U<<(rp-reserved);
2002				if (!(reported & mask)) {
2003					reported |= mask;
2004					dprintf(1, "\t%s => %s (%p)\n",
2005						name, ldso.name,
2006						ldso.base);
2007				}
2008			}
2009			is_self = 1;
2010		}
2011	}
2012	if (!strcmp(name, ldso.name)) is_self = 1;
2013	if (is_self) {
2014		if (!ldso.prev) {
2015			tail->next = &ldso;
2016			ldso.prev = tail;
2017			tail = &ldso;
2018			ldso.namespace = namespace;
2019			ns_add_dso(namespace, &ldso);
2020		}
2021		return &ldso;
2022	}
2023	if (strchr(name, '/')) {
2024		pathname = name;
2025
2026		if (!is_accessible(namespace, pathname, g_is_asan, check_inherited)) {
2027			fd = -1;
2028			LD_LOGD("load_library is_accessible return false,fd = -1");
2029		} else {
2030			fd = open(name, O_RDONLY|O_CLOEXEC);
2031			LD_LOGD("load_library is_accessible return true, open file fd:%{public}d .", fd);
2032		}
2033	} else {
2034		/* Search for the name to see if it's already loaded */
2035		/* Search in namespace */
2036		p = find_library_by_name(name, namespace, check_inherited);
2037		if (p) {
2038			LD_LOGD("load_library find_library_by_name found p, return it!");
2039			return p;
2040		}
2041		if (strlen(name) > NAME_MAX) {
2042			LD_LOGE("load_library name exceeding the maximum length, return 0!");
2043			return 0;
2044		}
2045		fd = -1;
2046		if (namespace->env_paths) fd = path_open(name, namespace->env_paths, buf, sizeof buf);
2047		for (p = needed_by; fd == -1 && p; p = p->needed_by) {
2048			if (fixup_rpath(p, buf, sizeof buf) < 0) {
2049				LD_LOGD("load_library Inhibit further search,fd = -2.");
2050				fd = -2; /* Inhibit further search. */
2051			}
2052			if (p->rpath) {
2053				fd = path_open(name, p->rpath, buf, sizeof buf);
2054				LD_LOGD("load_library  p->rpath path_open fd:%{public}d.", fd);
2055			}
2056
2057		}
2058		if (g_is_asan) {
2059			fd = handle_asan_path_open(fd, name, namespace, buf, sizeof buf);
2060			LD_LOGD("load_library handle_asan_path_open fd:%{public}d.", fd);
2061		} else {
2062			if (fd == -1 && namespace->lib_paths) {
2063				fd = path_open(name, namespace->lib_paths, buf, sizeof buf);
2064				LD_LOGD("load_library no asan lib_paths path_open fd:%{public}d.", fd);
2065			}
2066		}
2067		pathname = buf;
2068		LD_LOGD("load_library lib_paths pathname:%{public}s.", pathname);
2069	}
2070	if (fd < 0) {
2071		if (!check_inherited || !namespace->ns_inherits) return 0;
2072		/* Load lib in inherited namespace. Do not check inherited again.*/
2073		for (size_t i = 0; i < namespace->ns_inherits->num; i++) {
2074			ns_inherit *inherit = namespace->ns_inherits->inherits[i];
2075			if (strchr(name, '/')==0 && !is_sharable(inherit, name)) continue;
2076			p = load_library(name, needed_by, inherit->inherited_ns, false, reserved_params);
2077			if (p) {
2078				LD_LOGD("load_library search in inherited, found p ,inherited_ns name:%{public}s",
2079						inherit->inherited_ns->ns_name);
2080				return p;
2081			}
2082		}
2083		return 0;
2084	}
2085	if (fstat(fd, &st) < 0) {
2086		close(fd);
2087		LD_LOGE("load_library fstat < 0,return 0!");
2088		return 0;
2089	}
2090	/* Search in namespace */
2091	p = find_library_by_fstat(&st, namespace, check_inherited, 0);
2092	if (p) {
2093		/* If this library was previously loaded with a
2094		* pathname but a search found the same inode,
2095		* setup its shortname so it can be found by name. */
2096		if (!p->shortname && pathname != name)
2097			p->shortname = strrchr(p->name, '/')+1;
2098		close(fd);
2099		LD_LOGD("load_library find_library_by_fstat, found p and return it!");
2100		return p;
2101	}
2102	map = noload ? 0 : map_library(fd, &temp_dso, reserved_params);
2103	close(fd);
2104	if (!map) return 0;
2105
2106	/* Avoid the danger of getting two versions of libc mapped into the
2107	 * same process when an absolute pathname was used. The symbols
2108	 * checked are chosen to catch both musl and glibc, and to avoid
2109	 * false positives from interposition-hack libraries. */
2110	decode_dyn(&temp_dso);
2111	if (find_sym(&temp_dso, "__libc_start_main", 1).sym &&
2112		find_sym(&temp_dso, "stdin", 1).sym) {
2113		unmap_library(&temp_dso);
2114		return load_library("libc.so", needed_by, namespace, true, reserved_params);
2115	}
2116	/* Past this point, if we haven't reached runtime yet, ldso has
2117	 * committed either to use the mapped library or to abort execution.
2118	 * Unmapping is not possible, so we can safely reclaim gaps. */
2119	if (!runtime) reclaim_gaps(&temp_dso);
2120
2121	/* Allocate storage for the new DSO. When there is TLS, this
2122	 * storage must include a reservation for all pre-existing
2123	 * threads to obtain copies of both the new TLS, and an
2124	 * extended DTV capable of storing an additional slot for
2125	 * the newly-loaded DSO. */
2126	alloc_size = sizeof *p + strlen(pathname) + 1;
2127	if (runtime && temp_dso.tls.image) {
2128		size_t per_th = temp_dso.tls.size + temp_dso.tls.align
2129			+ sizeof(void *) * (tls_cnt+3);
2130		n_th = libc.threads_minus_1 + 1;
2131		if (n_th > SSIZE_MAX / per_th) alloc_size = SIZE_MAX;
2132		else alloc_size += n_th * per_th;
2133	}
2134	p = calloc(1, alloc_size);
2135	if (!p) {
2136		unmap_library(&temp_dso);
2137		return 0;
2138	}
2139	memcpy(p, &temp_dso, sizeof temp_dso);
2140	p->dev = st.st_dev;
2141	p->ino = st.st_ino;
2142	p->needed_by = needed_by;
2143	p->name = p->buf;
2144	p->runtime_loaded = runtime;
2145	strcpy(p->name, pathname);
2146	/* Add a shortname only if name arg was not an explicit pathname. */
2147	if (pathname != name) p->shortname = strrchr(p->name, '/')+1;
2148	if (p->tls.image) {
2149		p->tls_id = ++tls_cnt;
2150		tls_align = MAXP2(tls_align, p->tls.align);
2151#ifdef TLS_ABOVE_TP
2152		p->tls.offset = tls_offset + ( (p->tls.align-1) &
2153			(-tls_offset + (uintptr_t)p->tls.image) );
2154		tls_offset = p->tls.offset + p->tls.size;
2155#else
2156		tls_offset += p->tls.size + p->tls.align - 1;
2157		tls_offset -= (tls_offset + (uintptr_t)p->tls.image)
2158			& (p->tls.align-1);
2159		p->tls.offset = tls_offset;
2160#endif
2161		p->new_dtv = (void *)(-sizeof(size_t) &
2162			(uintptr_t)(p->name+strlen(p->name)+sizeof(size_t)));
2163		p->new_tls = (void *)(p->new_dtv + n_th*(tls_cnt+1));
2164		if (tls_tail) tls_tail->next = &p->tls;
2165		else libc.tls_head = &p->tls;
2166		tls_tail = &p->tls;
2167	}
2168
2169	tail->next = p;
2170	p->prev = tail;
2171	tail = p;
2172
2173	/* Add dso to namespace */
2174	p->namespace = namespace;
2175	ns_add_dso(namespace, p);
2176	if (runtime)
2177		p->by_dlopen = 1;
2178
2179	if (DL_FDPIC) makefuncdescs(p);
2180
2181	if (ldd_mode) dprintf(1, "\t%s => %s (%p)\n", name, pathname, p->base);
2182
2183	return p;
2184}
2185
2186static void load_direct_deps(struct dso *p, ns_t *namespace, struct reserved_address_params *reserved_params)
2187{
2188	size_t i, cnt=0;
2189
2190	if (p->deps) return;
2191	/* For head, all preloads are direct pseudo-dependencies.
2192	 * Count and include them now to avoid realloc later. */
2193	if (p==head) for (struct dso *q=p->next; q; q=q->next)
2194		cnt++;
2195	for (i=0; p->dynv[i]; i+=2)
2196		if (p->dynv[i] == DT_NEEDED) cnt++;
2197	/* Use builtin buffer for apps with no external deps, to
2198	 * preserve property of no runtime failure paths. */
2199	p->deps = (p==head && cnt<2) ? builtin_deps :
2200		calloc(cnt+1, sizeof *p->deps);
2201	if (!p->deps) {
2202		error("Error loading dependencies for %s", p->name);
2203		if (runtime) longjmp(*rtld_fail, 1);
2204	}
2205	cnt=0;
2206	if (p==head) for (struct dso *q=p->next; q; q=q->next)
2207		p->deps[cnt++] = q;
2208	for (i=0; p->dynv[i]; i+=2) {
2209		if (p->dynv[i] != DT_NEEDED) continue;
2210		struct dso *dep = load_library(p->strings + p->dynv[i+1], p, namespace, true, reserved_params);
2211		LD_LOGD("loading shared library %{public}s: (needed by %{public}s)", p->strings + p->dynv[i+1], p->name);
2212		if (!dep) {
2213			error("Error loading shared library %s: %m (needed by %s)",
2214				p->strings + p->dynv[i+1], p->name);
2215			if (runtime) longjmp(*rtld_fail, 1);
2216			continue;
2217		}
2218		p->deps[cnt++] = dep;
2219	}
2220	p->deps[cnt] = 0;
2221	p->ndeps_direct = cnt;
2222	for (i = 0; i < p->ndeps_direct; i++) {
2223		add_dso_parent(p->deps[i], p);
2224	}
2225}
2226
2227static void load_deps(struct dso *p, struct reserved_address_params *reserved_params)
2228{
2229	if (p->deps) return;
2230	for (; p; p=p->next)
2231		load_direct_deps(p, p->namespace, reserved_params);
2232}
2233#endif
2234
2235static void extend_bfs_deps(struct dso *p)
2236{
2237	size_t i, j, cnt, ndeps_all;
2238	struct dso **tmp;
2239
2240	/* Can't use realloc if the original p->deps was allocated at
2241	 * program entry and malloc has been replaced, or if it's
2242	 * the builtin non-allocated trivial main program deps array. */
2243	int no_realloc = (__malloc_replaced && !p->runtime_loaded)
2244		|| p->deps == builtin_deps;
2245
2246	if (p->bfs_built) return;
2247	ndeps_all = p->ndeps_direct;
2248
2249	/* Mark existing (direct) deps so they won't be duplicated. */
2250	for (i=0; p->deps[i]; i++)
2251		p->deps[i]->mark = 1;
2252
2253	/* For each dependency already in the list, copy its list of direct
2254	 * dependencies to the list, excluding any items already in the
2255	 * list. Note that the list this loop iterates over will grow during
2256	 * the loop, but since duplicates are excluded, growth is bounded. */
2257	for (i=0; p->deps[i]; i++) {
2258		struct dso *dep = p->deps[i];
2259		for (j=cnt=0; j<dep->ndeps_direct; j++)
2260			if (!dep->deps[j]->mark) cnt++;
2261		tmp = no_realloc ?
2262			malloc(sizeof(*tmp) * (ndeps_all+cnt+1)) :
2263			realloc(p->deps, sizeof(*tmp) * (ndeps_all+cnt+1));
2264		if (!tmp) {
2265			error("Error recording dependencies for %s", p->name);
2266			if (runtime) longjmp(*rtld_fail, 1);
2267			continue;
2268		}
2269		if (no_realloc) {
2270			memcpy(tmp, p->deps, sizeof(*tmp) * (ndeps_all+1));
2271			no_realloc = 0;
2272		}
2273		p->deps = tmp;
2274		for (j=0; j<dep->ndeps_direct; j++) {
2275			if (dep->deps[j]->mark) continue;
2276			dep->deps[j]->mark = 1;
2277			p->deps[ndeps_all++] = dep->deps[j];
2278		}
2279		p->deps[ndeps_all] = 0;
2280	}
2281	p->bfs_built = 1;
2282	for (p=head; p; p=p->next)
2283		p->mark = 0;
2284}
2285
2286#ifndef LOAD_ORDER_RANDOMIZATION
2287static void load_preload(char *s, ns_t *ns)
2288{
2289	int tmp;
2290	char *z;
2291	for (z=s; *z; s=z) {
2292		for (   ; *s && (isspace(*s) || *s==':'); s++);
2293		for (z=s; *z && !isspace(*z) && *z!=':'; z++);
2294		tmp = *z;
2295		*z = 0;
2296		load_library(s, 0, ns, true, NULL);
2297		*z = tmp;
2298	}
2299}
2300#endif
2301
2302static void add_syms(struct dso *p)
2303{
2304	if (!p->syms_next && syms_tail != p) {
2305		syms_tail->syms_next = p;
2306		syms_tail = p;
2307	}
2308}
2309
2310static void revert_syms(struct dso *old_tail)
2311{
2312	struct dso *p, *next;
2313	/* Chop off the tail of the list of dsos that participate in
2314	 * the global symbol table, reverting them to RTLD_LOCAL. */
2315	for (p=old_tail; p; p=next) {
2316		next = p->syms_next;
2317		p->syms_next = 0;
2318	}
2319	syms_tail = old_tail;
2320}
2321
2322static void do_mips_relocs(struct dso *p, size_t *got)
2323{
2324	size_t i, j, rel[2];
2325	unsigned char *base = p->base;
2326	i=0; search_vec(p->dynv, &i, DT_MIPS_LOCAL_GOTNO);
2327	if (p==&ldso) {
2328		got += i;
2329	} else {
2330		while (i--) *got++ += (size_t)base;
2331	}
2332	j=0; search_vec(p->dynv, &j, DT_MIPS_GOTSYM);
2333	i=0; search_vec(p->dynv, &i, DT_MIPS_SYMTABNO);
2334	Sym *sym = p->syms + j;
2335	rel[0] = (unsigned char *)got - base;
2336	for (i-=j; i; i--, sym++, rel[0]+=sizeof(size_t)) {
2337		rel[1] = R_INFO(sym-p->syms, R_MIPS_JUMP_SLOT);
2338		do_relocs(p, rel, sizeof rel, 2);
2339	}
2340}
2341
2342static uint8_t* sleb128_decoder(uint8_t* current, uint8_t* end, size_t* value)
2343{
2344	size_t result = 0;
2345	static const size_t size = CHAR_BIT * sizeof(result);
2346
2347	size_t shift = 0;
2348	uint8_t byte;
2349
2350	do {
2351		if (current >= end) {
2352			a_crash();
2353		}
2354
2355		byte = *current++;
2356		result |= ((size_t)(byte & 127) << shift);
2357		shift += 7;
2358	} while (byte & 128);
2359
2360	if (shift < size && (byte & 64)) {
2361		result |= -((size_t)(1) << shift);
2362	}
2363
2364	*value = result;
2365
2366	return current;
2367}
2368
2369static void do_android_relocs(struct dso *p, size_t dt_name, size_t dt_size)
2370{
2371	size_t android_rel_addr = 0, android_rel_size = 0;
2372	uint8_t *android_rel_curr, *android_rel_end;
2373
2374	search_vec(p->dynv, &android_rel_addr, dt_name);
2375	search_vec(p->dynv, &android_rel_size, dt_size);
2376
2377	if (!android_rel_addr || (android_rel_size < 4)) {
2378		return;
2379	}
2380
2381	android_rel_curr = laddr(p, android_rel_addr);
2382	if (memcmp(android_rel_curr, "APS2", ANDROID_REL_SIGN_SIZE)) {
2383		return;
2384	}
2385
2386	android_rel_curr += ANDROID_REL_SIGN_SIZE;
2387	android_rel_size -= ANDROID_REL_SIGN_SIZE;
2388
2389	android_rel_end = android_rel_curr + android_rel_size;
2390
2391	size_t relocs_num;
2392	size_t rel[3] = {0};
2393
2394	android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &relocs_num);
2395	android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &rel[0]);
2396
2397	for (size_t i = 0; i < relocs_num;) {
2398
2399		size_t group_size, group_flags;
2400
2401		android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &group_size);
2402		android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &group_flags);
2403
2404		size_t group_r_offset_delta = 0;
2405
2406		if (group_flags & RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG) {
2407			android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &group_r_offset_delta);
2408		}
2409
2410		if (group_flags & RELOCATION_GROUPED_BY_INFO_FLAG) {
2411			android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &rel[1]);
2412		}
2413
2414		const size_t addend_flags = group_flags & (RELOCATION_GROUP_HAS_ADDEND_FLAG | RELOCATION_GROUPED_BY_ADDEND_FLAG);
2415
2416		if (addend_flags == RELOCATION_GROUP_HAS_ADDEND_FLAG) {
2417		} else if (addend_flags == (RELOCATION_GROUP_HAS_ADDEND_FLAG | RELOCATION_GROUPED_BY_ADDEND_FLAG)) {
2418			size_t addend;
2419			android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &addend);
2420			rel[2] += addend;
2421		} else {
2422			rel[2] = 0;
2423		}
2424
2425		for (size_t j = 0; j < group_size; j++) {
2426			if (group_flags & RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG) {
2427				rel[0] += group_r_offset_delta;
2428			} else {
2429				size_t offset_detla;
2430				android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &offset_detla);
2431
2432				rel[0] += offset_detla;
2433			}
2434
2435			if ((group_flags & RELOCATION_GROUPED_BY_INFO_FLAG) == 0) {
2436				android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &rel[1]);
2437			}
2438
2439			if (addend_flags == RELOCATION_GROUP_HAS_ADDEND_FLAG) {
2440				size_t addend;
2441				android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &addend);
2442				rel[2] += addend;
2443			}
2444
2445			if (dt_name == DT_ANDROID_REL) {
2446				do_relocs(p, rel, sizeof(size_t)*2, 2);
2447			} else {
2448				do_relocs(p, rel, sizeof(size_t)*3, 3);
2449			}
2450		}
2451
2452		i += group_size;
2453	}
2454}
2455
2456static void do_relr_relocs(struct dso *dso, size_t *relr, size_t relr_size)
2457{
2458	unsigned char *base = dso->base;
2459	size_t *reloc_addr;
2460	for (; relr_size; relr++, relr_size-=sizeof(size_t))
2461		if ((relr[0]&1) == 0) {
2462			reloc_addr = laddr(dso, relr[0]);
2463			*reloc_addr++ += (size_t)base;
2464		} else {
2465			int i = 0;
2466			for (size_t bitmap=relr[0]; (bitmap>>=1); i++)
2467				if (bitmap&1)
2468					reloc_addr[i] += (size_t)base;
2469			reloc_addr += 8*sizeof(size_t)-1;
2470		}
2471}
2472
2473static void reloc_all(struct dso *p, const dl_extinfo *extinfo)
2474{
2475	ssize_t relro_fd_offset = 0;
2476	size_t dyn[DYN_CNT];
2477	for (; p; p=p->next) {
2478		if (p->relocated) continue;
2479		if (p != &ldso) {
2480			add_can_search_so_list_in_dso(p, head);
2481		}
2482		decode_vec(p->dynv, dyn, DYN_CNT);
2483		if (NEED_MIPS_GOT_RELOCS)
2484			do_mips_relocs(p, laddr(p, dyn[DT_PLTGOT]));
2485		do_relocs(p, laddr(p, dyn[DT_JMPREL]), dyn[DT_PLTRELSZ],
2486			2+(dyn[DT_PLTREL]==DT_RELA));
2487		do_relocs(p, laddr(p, dyn[DT_REL]), dyn[DT_RELSZ], 2);
2488		do_relocs(p, laddr(p, dyn[DT_RELA]), dyn[DT_RELASZ], 3);
2489		if (!DL_FDPIC)
2490			do_relr_relocs(p, laddr(p, dyn[DT_RELR]), dyn[DT_RELRSZ]);
2491
2492		do_android_relocs(p, DT_ANDROID_REL, DT_ANDROID_RELSZ);
2493		do_android_relocs(p, DT_ANDROID_RELA, DT_ANDROID_RELASZ);
2494
2495		if (head != &ldso && p->relro_start != p->relro_end &&
2496			mprotect(laddr(p, p->relro_start), p->relro_end-p->relro_start, PROT_READ)
2497			&& errno != ENOSYS) {
2498			error("Error relocating %s: RELRO protection failed: %m",
2499				p->name);
2500			if (runtime) longjmp(*rtld_fail, 1);
2501		}
2502		/* Handle serializing/mapping the RELRO segment */
2503		handle_relro_sharing(p, extinfo, &relro_fd_offset);
2504
2505		p->relocated = 1;
2506		free_reloc_can_search_dso(p);
2507	}
2508}
2509
2510static void kernel_mapped_dso(struct dso *p)
2511{
2512	size_t min_addr = -1, max_addr = 0, cnt;
2513	Phdr *ph = p->phdr;
2514	for (cnt = p->phnum; cnt--; ph = (void *)((char *)ph + p->phentsize)) {
2515		if (ph->p_type == PT_DYNAMIC) {
2516			p->dynv = laddr(p, ph->p_vaddr);
2517		} else if (ph->p_type == PT_GNU_RELRO) {
2518			p->relro_start = ph->p_vaddr & -PAGE_SIZE;
2519			p->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE;
2520		} else if (ph->p_type == PT_GNU_STACK) {
2521			if (!runtime && ph->p_memsz > __default_stacksize) {
2522				__default_stacksize =
2523					ph->p_memsz < DEFAULT_STACK_MAX ?
2524					ph->p_memsz : DEFAULT_STACK_MAX;
2525			}
2526		}
2527		if (ph->p_type != PT_LOAD) continue;
2528		if (ph->p_vaddr < min_addr)
2529			min_addr = ph->p_vaddr;
2530		if (ph->p_vaddr+ph->p_memsz > max_addr)
2531			max_addr = ph->p_vaddr+ph->p_memsz;
2532	}
2533	min_addr &= -PAGE_SIZE;
2534	max_addr = (max_addr + PAGE_SIZE-1) & -PAGE_SIZE;
2535	p->map = p->base + min_addr;
2536	p->map_len = max_addr - min_addr;
2537	p->kernel_mapped = 1;
2538}
2539
2540void __libc_exit_fini()
2541{
2542	struct dso *p;
2543	size_t dyn[DYN_CNT];
2544	pthread_t self = __pthread_self();
2545
2546	/* Take both locks before setting shutting_down, so that
2547	 * either lock is sufficient to read its value. The lock
2548	 * order matches that in dlopen to avoid deadlock. */
2549	pthread_rwlock_wrlock(&lock);
2550	pthread_mutex_lock(&init_fini_lock);
2551	shutting_down = 1;
2552	pthread_rwlock_unlock(&lock);
2553	for (p=fini_head; p; p=p->fini_next) {
2554		while (p->ctor_visitor && p->ctor_visitor!=self)
2555			pthread_cond_wait(&ctor_cond, &init_fini_lock);
2556		if (!p->constructed) continue;
2557		decode_vec(p->dynv, dyn, DYN_CNT);
2558		if (dyn[0] & (1<<DT_FINI_ARRAY)) {
2559			size_t n = dyn[DT_FINI_ARRAYSZ]/sizeof(size_t);
2560			size_t *fn = (size_t *)laddr(p, dyn[DT_FINI_ARRAY])+n;
2561			while (n--) ((void (*)(void))*--fn)();
2562		}
2563#ifndef NO_LEGACY_INITFINI
2564		if ((dyn[0] & (1<<DT_FINI)) && dyn[DT_FINI])
2565			fpaddr(p, dyn[DT_FINI])();
2566#endif
2567	}
2568}
2569
2570void __ldso_atfork(int who)
2571{
2572	if (who<0) {
2573		pthread_rwlock_wrlock(&lock);
2574		pthread_mutex_lock(&init_fini_lock);
2575	} else {
2576		pthread_mutex_unlock(&init_fini_lock);
2577		pthread_rwlock_unlock(&lock);
2578	}
2579}
2580
2581static struct dso **queue_ctors(struct dso *dso)
2582{
2583	size_t cnt, qpos, spos, i;
2584	struct dso *p, **queue, **stack;
2585
2586	if (ldd_mode) return 0;
2587
2588	/* Bound on queue size is the total number of indirect deps.
2589	 * If a bfs deps list was built, we can use it. Otherwise,
2590	 * bound by the total number of DSOs, which is always safe and
2591	 * is reasonable we use it (for main app at startup). */
2592	if (dso->bfs_built) {
2593		for (cnt=0; dso->deps[cnt]; cnt++)
2594			dso->deps[cnt]->mark = 0;
2595		cnt++; /* self, not included in deps */
2596	} else {
2597		for (cnt=0, p=head; p; cnt++, p=p->next)
2598			p->mark = 0;
2599	}
2600	cnt++; /* termination slot */
2601	if (dso==head && cnt <= countof(builtin_ctor_queue))
2602		queue = builtin_ctor_queue;
2603	else
2604		queue = calloc(cnt, sizeof *queue);
2605
2606	if (!queue) {
2607		error("Error allocating constructor queue: %m\n");
2608		if (runtime) longjmp(*rtld_fail, 1);
2609		return 0;
2610	}
2611
2612	/* Opposite ends of the allocated buffer serve as an output queue
2613	 * and a working stack. Setup initial stack with just the argument
2614	 * dso and initial queue empty... */
2615	stack = queue;
2616	qpos = 0;
2617	spos = cnt;
2618	stack[--spos] = dso;
2619	dso->next_dep = 0;
2620	dso->mark = 1;
2621
2622	/* Then perform pseudo-DFS sort, but ignoring circular deps. */
2623	while (spos<cnt) {
2624		p = stack[spos++];
2625		while (p->next_dep < p->ndeps_direct) {
2626			if (p->deps[p->next_dep]->mark) {
2627				p->next_dep++;
2628			} else {
2629				stack[--spos] = p;
2630				p = p->deps[p->next_dep];
2631				p->next_dep = 0;
2632				p->mark = 1;
2633			}
2634		}
2635		queue[qpos++] = p;
2636	}
2637	queue[qpos] = 0;
2638	for (i=0; i<qpos; i++) queue[i]->mark = 0;
2639
2640	return queue;
2641}
2642
2643static void do_init_fini(struct dso **queue)
2644{
2645	struct dso *p;
2646	size_t dyn[DYN_CNT], i;
2647	pthread_t self = __pthread_self();
2648
2649	pthread_mutex_lock(&init_fini_lock);
2650	for (i=0; (p=queue[i]); i++) {
2651		while ((p->ctor_visitor && p->ctor_visitor!=self) || shutting_down)
2652			pthread_cond_wait(&ctor_cond, &init_fini_lock);
2653		if (p->ctor_visitor || p->constructed)
2654			continue;
2655		p->ctor_visitor = self;
2656
2657		decode_vec(p->dynv, dyn, DYN_CNT);
2658		if (dyn[0] & ((1<<DT_FINI) | (1<<DT_FINI_ARRAY))) {
2659			p->fini_next = fini_head;
2660			fini_head = p;
2661		}
2662
2663		pthread_mutex_unlock(&init_fini_lock);
2664
2665#ifndef NO_LEGACY_INITFINI
2666		if ((dyn[0] & (1<<DT_INIT)) && dyn[DT_INIT])
2667			fpaddr(p, dyn[DT_INIT])();
2668#endif
2669		if (dyn[0] & (1<<DT_INIT_ARRAY)) {
2670			size_t n = dyn[DT_INIT_ARRAYSZ]/sizeof(size_t);
2671			size_t *fn = laddr(p, dyn[DT_INIT_ARRAY]);
2672			if (p != &ldso) {
2673				trace_marker_begin(HITRACE_TAG_MUSL, "calling constructors: ", p->name);
2674			}
2675			while (n--) ((void (*)(void))*fn++)();
2676			if (p != &ldso) {
2677				trace_marker_end(HITRACE_TAG_MUSL);
2678			}
2679		}
2680
2681		pthread_mutex_lock(&init_fini_lock);
2682		p->ctor_visitor = 0;
2683		p->constructed = 1;
2684		pthread_cond_broadcast(&ctor_cond);
2685	}
2686	pthread_mutex_unlock(&init_fini_lock);
2687}
2688
2689void __libc_start_init(void)
2690{
2691	do_init_fini(main_ctor_queue);
2692	if (!__malloc_replaced && main_ctor_queue != builtin_ctor_queue)
2693		free(main_ctor_queue);
2694	main_ctor_queue = 0;
2695}
2696
2697static void dl_debug_state(void)
2698{
2699}
2700
2701weak_alias(dl_debug_state, _dl_debug_state);
2702
2703void __init_tls(size_t *auxv)
2704{
2705}
2706
2707static void update_tls_size()
2708{
2709	libc.tls_cnt = tls_cnt;
2710	libc.tls_align = tls_align;
2711	libc.tls_size = ALIGN(
2712		(1+tls_cnt) * sizeof(void *) +
2713		tls_offset +
2714		sizeof(struct pthread) +
2715		tls_align * 2,
2716	tls_align);
2717}
2718
2719static void install_new_tls(void)
2720{
2721	sigset_t set;
2722	pthread_t self = __pthread_self(), td;
2723	struct dso *dtv_provider = container_of(tls_tail, struct dso, tls);
2724	uintptr_t (*newdtv)[tls_cnt+1] = (void *)dtv_provider->new_dtv;
2725	struct dso *p;
2726	size_t i, j;
2727	size_t old_cnt = self->dtv[0];
2728
2729	__block_app_sigs(&set);
2730	__tl_lock();
2731	/* Copy existing dtv contents from all existing threads. */
2732	for (i=0, td=self; !i || td!=self; i++, td=td->next) {
2733		memcpy(newdtv+i, td->dtv,
2734			(old_cnt+1)*sizeof(uintptr_t));
2735		newdtv[i][0] = tls_cnt;
2736	}
2737	/* Install new dtls into the enlarged, uninstalled dtv copies. */
2738	for (p=head; ; p=p->next) {
2739		if (p->tls_id <= old_cnt) continue;
2740		unsigned char *mem = p->new_tls;
2741		for (j=0; j<i; j++) {
2742			unsigned char *new = mem;
2743			new += ((uintptr_t)p->tls.image - (uintptr_t)mem)
2744				& (p->tls.align-1);
2745			memcpy(new, p->tls.image, p->tls.len);
2746			newdtv[j][p->tls_id] =
2747				(uintptr_t)new + DTP_OFFSET;
2748			mem += p->tls.size + p->tls.align;
2749		}
2750		if (p->tls_id == tls_cnt) break;
2751	}
2752
2753	/* Broadcast barrier to ensure contents of new dtv is visible
2754	 * if the new dtv pointer is. The __membarrier function has a
2755	 * fallback emulation using signals for kernels that lack the
2756	 * feature at the syscall level. */
2757
2758	__membarrier(MEMBARRIER_CMD_PRIVATE_EXPEDITED, 0);
2759
2760	/* Install new dtv for each thread. */
2761	for (j=0, td=self; !j || td!=self; j++, td=td->next) {
2762		td->dtv = newdtv[j];
2763	}
2764
2765	__tl_unlock();
2766	__restore_sigs(&set);
2767}
2768
2769/* Stage 1 of the dynamic linker is defined in dlstart.c. It calls the
2770 * following stage 2 and stage 3 functions via primitive symbolic lookup
2771 * since it does not have access to their addresses to begin with. */
2772
2773/* Stage 2 of the dynamic linker is called after relative relocations
2774 * have been processed. It can make function calls to static functions
2775 * and access string literals and static data, but cannot use extern
2776 * symbols. Its job is to perform symbolic relocations on the dynamic
2777 * linker itself, but some of the relocations performed may need to be
2778 * replaced later due to copy relocations in the main program. */
2779
2780hidden void __dls2(unsigned char *base, size_t *sp)
2781{
2782	size_t *auxv;
2783	for (auxv=sp+1+*sp+1; *auxv; auxv++);
2784	auxv++;
2785	if (DL_FDPIC) {
2786		void *p1 = (void *)sp[-2];
2787		void *p2 = (void *)sp[-1];
2788		if (!p1) {
2789			size_t aux[AUX_CNT];
2790			decode_vec(auxv, aux, AUX_CNT);
2791			if (aux[AT_BASE]) ldso.base = (void *)aux[AT_BASE];
2792			else ldso.base = (void *)(aux[AT_PHDR] & -4096);
2793		}
2794		app_loadmap = p2 ? p1 : 0;
2795		ldso.loadmap = p2 ? p2 : p1;
2796		ldso.base = laddr(&ldso, 0);
2797	} else {
2798		ldso.base = base;
2799	}
2800	size_t aux[AUX_CNT];
2801	decode_vec(auxv, aux, AUX_CNT);
2802	libc.page_size = aux[AT_PAGESZ];
2803	Ehdr *ehdr = (void *)ldso.base;
2804	ldso.name = ldso.shortname = "libc.so";
2805	ldso.phnum = ehdr->e_phnum;
2806	ldso.phdr = laddr(&ldso, ehdr->e_phoff);
2807	ldso.phentsize = ehdr->e_phentsize;
2808	ldso.is_global = true;
2809	kernel_mapped_dso(&ldso);
2810	decode_dyn(&ldso);
2811
2812	if (DL_FDPIC) makefuncdescs(&ldso);
2813
2814	/* Prepare storage for to save clobbered REL addends so they
2815	 * can be reused in stage 3. There should be very few. If
2816	 * something goes wrong and there are a huge number, abort
2817	 * instead of risking stack overflow. */
2818	size_t dyn[DYN_CNT];
2819	decode_vec(ldso.dynv, dyn, DYN_CNT);
2820	size_t *rel = laddr(&ldso, dyn[DT_REL]);
2821	size_t rel_size = dyn[DT_RELSZ];
2822	size_t symbolic_rel_cnt = 0;
2823	apply_addends_to = rel;
2824	for (; rel_size; rel+=2, rel_size-=2*sizeof(size_t))
2825		if (!IS_RELATIVE(rel[1], ldso.syms)) symbolic_rel_cnt++;
2826	if (symbolic_rel_cnt >= ADDEND_LIMIT) a_crash();
2827	size_t addends[symbolic_rel_cnt+1];
2828	saved_addends = addends;
2829
2830	head = &ldso;
2831	reloc_all(&ldso, NULL);
2832
2833	ldso.relocated = 0;
2834
2835	/* Call dynamic linker stage-2b, __dls2b, looking it up
2836	 * symbolically as a barrier against moving the address
2837	 * load across the above relocation processing. */
2838	struct symdef dls2b_def = find_sym(&ldso, "__dls2b", 0);
2839	if (DL_FDPIC) ((stage3_func)&ldso.funcdescs[dls2b_def.sym-ldso.syms])(sp, auxv, aux);
2840	else ((stage3_func)laddr(&ldso, dls2b_def.sym->st_value))(sp, auxv, aux);
2841}
2842
2843/* Stage 2b sets up a valid thread pointer, which requires relocations
2844 * completed in stage 2, and on which stage 3 is permitted to depend.
2845 * This is done as a separate stage, with symbolic lookup as a barrier,
2846 * so that loads of the thread pointer and &errno can be pure/const and
2847 * thereby hoistable. */
2848
2849void __dls2b(size_t *sp, size_t *auxv, size_t *aux)
2850{
2851	/* Setup early thread pointer in builtin_tls for ldso/libc itself to
2852	 * use during dynamic linking. If possible it will also serve as the
2853	 * thread pointer at runtime. */
2854	search_vec(auxv, &__hwcap, AT_HWCAP);
2855	libc.auxv = auxv;
2856	libc.tls_size = sizeof builtin_tls;
2857	libc.tls_align = tls_align;
2858	if (__init_tp(__copy_tls((void *)builtin_tls)) < 0) {
2859		a_crash();
2860	}
2861	__pthread_self()->stack = (void *)(sp + 1);
2862	struct symdef dls3_def = find_sym(&ldso, "__dls3", 0);
2863	if (DL_FDPIC) ((stage3_func)&ldso.funcdescs[dls3_def.sym-ldso.syms])(sp, auxv, aux);
2864	else ((stage3_func)laddr(&ldso, dls3_def.sym->st_value))(sp, auxv, aux);
2865}
2866
2867/* Stage 3 of the dynamic linker is called with the dynamic linker/libc
2868 * fully functional. Its job is to load (if not already loaded) and
2869 * process dependencies and relocations for the main application and
2870 * transfer control to its entry point. */
2871
2872void __dls3(size_t *sp, size_t *auxv, size_t *aux)
2873{
2874	static struct dso app, vdso;
2875	size_t i;
2876	char *env_preload=0;
2877	char *replace_argv0=0;
2878	size_t vdso_base;
2879	int argc = *sp;
2880	char **argv = (void *)(sp+1);
2881	char **argv_orig = argv;
2882	char **envp = argv+argc+1;
2883
2884	/* Find aux vector just past environ[] and use it to initialize
2885	 * global data that may be needed before we can make syscalls. */
2886	__environ = envp;
2887	search_vec(auxv, &__sysinfo, AT_SYSINFO);
2888	__pthread_self()->sysinfo = __sysinfo;
2889	libc.secure = ((aux[0]&0x7800)!=0x7800 || aux[AT_UID]!=aux[AT_EUID]
2890		|| aux[AT_GID]!=aux[AT_EGID] || aux[AT_SECURE]);
2891
2892	/* Only trust user/env if kernel says we're not suid/sgid */
2893	if (!libc.secure) {
2894		env_path = getenv("LD_LIBRARY_PATH");
2895		env_preload = getenv("LD_PRELOAD");
2896	}
2897#ifdef OHOS_ENABLE_PARAMETER
2898	InitParameterClient();
2899#endif
2900// we may abort when linking other libs, load signal handler before stage start
2901#ifdef DFX_SIGNAL_LIBC
2902	DFX_InstallSignalHandler();
2903#endif
2904	__init_fdsan();
2905	/* If the main program was already loaded by the kernel,
2906	 * AT_PHDR will point to some location other than the dynamic
2907	 * linker's program headers. */
2908	if (aux[AT_PHDR] != (size_t)ldso.phdr) {
2909		size_t interp_off = 0;
2910		size_t tls_image = 0;
2911		/* Find load address of the main program, via AT_PHDR vs PT_PHDR. */
2912		Phdr *phdr = app.phdr = (void *)aux[AT_PHDR];
2913		app.phnum = aux[AT_PHNUM];
2914		app.phentsize = aux[AT_PHENT];
2915		for (i=aux[AT_PHNUM]; i; i--, phdr=(void *)((char *)phdr + aux[AT_PHENT])) {
2916			if (phdr->p_type == PT_PHDR)
2917				app.base = (void *)(aux[AT_PHDR] - phdr->p_vaddr);
2918			else if (phdr->p_type == PT_INTERP)
2919				interp_off = (size_t)phdr->p_vaddr;
2920			else if (phdr->p_type == PT_TLS) {
2921				tls_image = phdr->p_vaddr;
2922				app.tls.len = phdr->p_filesz;
2923				app.tls.size = phdr->p_memsz;
2924				app.tls.align = phdr->p_align;
2925			}
2926		}
2927		if (DL_FDPIC) app.loadmap = app_loadmap;
2928		if (app.tls.size) app.tls.image = laddr(&app, tls_image);
2929		if (interp_off) ldso.name = laddr(&app, interp_off);
2930		if ((aux[0] & (1UL<<AT_EXECFN))
2931			&& strncmp((char *)aux[AT_EXECFN], "/proc/", 6))
2932			app.name = (char *)aux[AT_EXECFN];
2933		else
2934			app.name = argv[0];
2935		kernel_mapped_dso(&app);
2936	} else {
2937		int fd;
2938		char *ldname = argv[0];
2939		size_t l = strlen(ldname);
2940		if (l >= 3 && !strcmp(ldname+l-3, "ldd")) ldd_mode = 1;
2941		argv++;
2942		while (argv[0] && argv[0][0]=='-' && argv[0][1]=='-') {
2943			char *opt = argv[0]+2;
2944			*argv++ = (void *)-1;
2945			if (!*opt) {
2946				break;
2947			} else if (!memcmp(opt, "list", 5)) {
2948				ldd_mode = 1;
2949			} else if (!memcmp(opt, "library-path", 12)) {
2950				if (opt[12]=='=') env_path = opt+13;
2951				else if (opt[12]) *argv = 0;
2952				else if (*argv) env_path = *argv++;
2953			} else if (!memcmp(opt, "preload", 7)) {
2954				if (opt[7]=='=') env_preload = opt+8;
2955				else if (opt[7]) *argv = 0;
2956				else if (*argv) env_preload = *argv++;
2957			} else if (!memcmp(opt, "argv0", 5)) {
2958				if (opt[5]=='=') replace_argv0 = opt+6;
2959				else if (opt[5]) *argv = 0;
2960				else if (*argv) replace_argv0 = *argv++;
2961			} else {
2962				argv[0] = 0;
2963			}
2964		}
2965		argv[-1] = (void *)(argc - (argv-argv_orig));
2966		if (!argv[0]) {
2967			dprintf(2, "musl libc (" LDSO_ARCH ")\n"
2968				"Version %s\n"
2969				"Dynamic Program Loader\n"
2970				"Usage: %s [options] [--] pathname%s\n",
2971				__libc_version, ldname,
2972				ldd_mode ? "" : " [args]");
2973			_exit(1);
2974		}
2975		fd = open(argv[0], O_RDONLY);
2976		if (fd < 0) {
2977			dprintf(2, "%s: cannot load %s: %s\n", ldname, argv[0], strerror(errno));
2978			_exit(1);
2979		}
2980		Ehdr *ehdr = map_library(fd, &app, NULL);
2981		if (!ehdr) {
2982			dprintf(2, "%s: %s: Not a valid dynamic program\n", ldname, argv[0]);
2983			_exit(1);
2984		}
2985		close(fd);
2986		ldso.name = ldname;
2987		app.name = argv[0];
2988		aux[AT_ENTRY] = (size_t)laddr(&app, ehdr->e_entry);
2989		/* Find the name that would have been used for the dynamic
2990		 * linker had ldd not taken its place. */
2991		if (ldd_mode) {
2992			for (i=0; i<app.phnum; i++) {
2993				if (app.phdr[i].p_type == PT_INTERP)
2994					ldso.name = laddr(&app, app.phdr[i].p_vaddr);
2995			}
2996			dprintf(1, "\t%s (%p)\n", ldso.name, ldso.base);
2997		}
2998	}
2999	if (app.tls.size) {
3000		libc.tls_head = tls_tail = &app.tls;
3001		app.tls_id = tls_cnt = 1;
3002#ifdef TLS_ABOVE_TP
3003		app.tls.offset = GAP_ABOVE_TP;
3004		app.tls.offset += (-GAP_ABOVE_TP + (uintptr_t)app.tls.image)
3005			& (app.tls.align-1);
3006		tls_offset = app.tls.offset + app.tls.size;
3007#else
3008		tls_offset = app.tls.offset = app.tls.size
3009			+ ( -((uintptr_t)app.tls.image + app.tls.size)
3010			& (app.tls.align-1) );
3011#endif
3012		tls_align = MAXP2(tls_align, app.tls.align);
3013	}
3014	decode_dyn(&app);
3015	if (DL_FDPIC) {
3016		makefuncdescs(&app);
3017		if (!app.loadmap) {
3018			app.loadmap = (void *)&app_dummy_loadmap;
3019			app.loadmap->nsegs = 1;
3020			app.loadmap->segs[0].addr = (size_t)app.map;
3021			app.loadmap->segs[0].p_vaddr = (size_t)app.map
3022				- (size_t)app.base;
3023			app.loadmap->segs[0].p_memsz = app.map_len;
3024		}
3025		argv[-3] = (void *)app.loadmap;
3026	}
3027	app.is_global = true;
3028
3029	/* Initial dso chain consists only of the app. */
3030	head = tail = syms_tail = &app;
3031
3032	/* Donate unused parts of app and library mapping to malloc */
3033	reclaim_gaps(&app);
3034	reclaim_gaps(&ldso);
3035
3036	find_and_set_bss_name(&app);
3037	find_and_set_bss_name(&ldso);
3038
3039	/* Load preload/needed libraries, add symbols to global namespace. */
3040	ldso.deps = (struct dso **)no_deps;
3041	/* Init g_is_asan */
3042	g_is_asan = false;
3043	LD_LOGD("__dls3 ldso.name:%{public}s.", ldso.name);
3044	/* Through ldso Name to judge whether the Asan function is enabled */
3045	if (strstr(ldso.name, "-asan")) {
3046		g_is_asan = true;
3047		LD_LOGD("__dls3 g_is_asan is true.");
3048	}
3049	/* Init all namespaces by config file. there is a default namespace always*/
3050	init_namespace(&app);
3051
3052#ifdef LOAD_ORDER_RANDOMIZATION
3053	struct loadtasks *tasks = create_loadtasks();
3054	if (!tasks) {
3055		_exit(1);
3056	}
3057	if (env_preload) {
3058		load_preload(env_preload, get_default_ns(), tasks);
3059	}
3060	for (struct dso *q=head; q; q=q->next) {
3061		q->is_global = true;
3062	}
3063	preload_deps(&app, tasks);
3064	unmap_preloaded_sections(tasks);
3065	shuffle_loadtasks(tasks);
3066	run_loadtasks(tasks, NULL);
3067	free_loadtasks(tasks);
3068	assign_tls(app.next);
3069#else
3070	if (env_preload) load_preload(env_preload, get_default_ns());
3071	for (struct dso *q=head; q; q=q->next) {
3072		q->is_global = true;
3073	}
3074 	load_deps(&app, NULL);
3075#endif
3076
3077	/* Set is_reloc_head_so_dep to true for all direct and indirect dependent sos of app, including app self. */
3078	for (struct dso *p=head; p; p=p->next) {
3079		p->is_reloc_head_so_dep = true;
3080		add_syms(p);
3081	}
3082
3083	/* Attach to vdso, if provided by the kernel, last so that it does
3084	 * not become part of the global namespace.  */
3085	if (search_vec(auxv, &vdso_base, AT_SYSINFO_EHDR) && vdso_base) {
3086		Ehdr *ehdr = (void *)vdso_base;
3087		Phdr *phdr = vdso.phdr = (void *)(vdso_base + ehdr->e_phoff);
3088		vdso.phnum = ehdr->e_phnum;
3089		vdso.phentsize = ehdr->e_phentsize;
3090		for (i=ehdr->e_phnum; i; i--, phdr=(void *)((char *)phdr + ehdr->e_phentsize)) {
3091			if (phdr->p_type == PT_DYNAMIC)
3092				vdso.dynv = (void *)(vdso_base + phdr->p_offset);
3093			if (phdr->p_type == PT_LOAD)
3094				vdso.base = (void *)(vdso_base - phdr->p_vaddr + phdr->p_offset);
3095		}
3096		vdso.name = "";
3097		vdso.shortname = "linux-gate.so.1";
3098		vdso.relocated = 1;
3099		vdso.deps = (struct dso **)no_deps;
3100		decode_dyn(&vdso);
3101		vdso.prev = tail;
3102		tail->next = &vdso;
3103		tail = &vdso;
3104		vdso.namespace = get_default_ns();
3105		ns_add_dso(vdso.namespace, &vdso);
3106	}
3107
3108	for (i=0; app.dynv[i]; i+=2) {
3109		if (!DT_DEBUG_INDIRECT && app.dynv[i]==DT_DEBUG)
3110			app.dynv[i+1] = (size_t)&debug;
3111		if (DT_DEBUG_INDIRECT && app.dynv[i]==DT_DEBUG_INDIRECT) {
3112			size_t *ptr = (size_t *) app.dynv[i+1];
3113			*ptr = (size_t)&debug;
3114		}
3115	}
3116
3117	/* This must be done before final relocations, since it calls
3118	 * malloc, which may be provided by the application. Calling any
3119	 * application code prior to the jump to its entry point is not
3120	 * valid in our model and does not work with FDPIC, where there
3121	 * are additional relocation-like fixups that only the entry point
3122	 * code can see to perform. */
3123	main_ctor_queue = queue_ctors(&app);
3124
3125	/* Initial TLS must also be allocated before final relocations
3126	 * might result in calloc being a call to application code. */
3127	update_tls_size();
3128	void *initial_tls = builtin_tls;
3129	if (libc.tls_size > sizeof builtin_tls || tls_align > MIN_TLS_ALIGN) {
3130		initial_tls = calloc(libc.tls_size, 1);
3131		if (!initial_tls) {
3132			dprintf(2, "%s: Error getting %zu bytes thread-local storage: %m\n",
3133				argv[0], libc.tls_size);
3134			_exit(127);
3135		}
3136	}
3137	static_tls_cnt = tls_cnt;
3138
3139	/* The main program must be relocated LAST since it may contain
3140	 * copy relocations which depend on libraries' relocations. */
3141	reloc_all(app.next, NULL);
3142	reloc_all(&app, NULL);
3143	for (struct dso *q=head; q; q=q->next) {
3144		q->is_reloc_head_so_dep = false;
3145	}
3146
3147	/* Actual copying to new TLS needs to happen after relocations,
3148	 * since the TLS images might have contained relocated addresses. */
3149	if (initial_tls != builtin_tls) {
3150		pthread_t self = __pthread_self();
3151		pthread_t td = __copy_tls(initial_tls);
3152		if (__init_tp(td) < 0) {
3153			a_crash();
3154		}
3155		td->tsd = self->tsd;
3156	} else {
3157		size_t tmp_tls_size = libc.tls_size;
3158		pthread_t self = __pthread_self();
3159		/* Temporarily set the tls size to the full size of
3160		 * builtin_tls so that __copy_tls will use the same layout
3161		 * as it did for before. Then check, just to be safe. */
3162		libc.tls_size = sizeof builtin_tls;
3163		if (__copy_tls((void*)builtin_tls) != self) a_crash();
3164		libc.tls_size = tmp_tls_size;
3165	}
3166
3167	if (init_cfi_shadow(head, &ldso) == CFI_FAILED) {
3168		error("[%s] init_cfi_shadow failed: %m", __FUNCTION__);
3169	}
3170
3171	if (ldso_fail) _exit(127);
3172	if (ldd_mode) _exit(0);
3173
3174	/* Determine if malloc was interposed by a replacement implementation
3175	 * so that calloc and the memalign family can harden against the
3176	 * possibility of incomplete replacement. */
3177	if (find_sym(head, "malloc", 1).dso != &ldso)
3178		__malloc_replaced = 1;
3179	if (find_sym(head, "aligned_alloc", 1).dso != &ldso)
3180		__aligned_alloc_replaced = 1;
3181
3182	/* Switch to runtime mode: any further failures in the dynamic
3183	 * linker are a reportable failure rather than a fatal startup
3184	 * error. */
3185	runtime = 1;
3186
3187	sync_with_debugger();
3188
3189	if (replace_argv0) argv[0] = replace_argv0;
3190
3191#ifdef USE_GWP_ASAN
3192	init_gwp_asan_by_libc(false);
3193#endif
3194
3195	errno = 0;
3196
3197	CRTJMP((void *)aux[AT_ENTRY], argv-1);
3198	for(;;);
3199}
3200
3201static void prepare_lazy(struct dso *p)
3202{
3203	size_t dyn[DYN_CNT], n, flags1=0;
3204	decode_vec(p->dynv, dyn, DYN_CNT);
3205	search_vec(p->dynv, &flags1, DT_FLAGS_1);
3206	if (dyn[DT_BIND_NOW] || (dyn[DT_FLAGS] & DF_BIND_NOW) || (flags1 & DF_1_NOW))
3207		return;
3208	n = dyn[DT_RELSZ]/2 + dyn[DT_RELASZ]/3 + dyn[DT_PLTRELSZ]/2 + 1;
3209	if (NEED_MIPS_GOT_RELOCS) {
3210		size_t j=0; search_vec(p->dynv, &j, DT_MIPS_GOTSYM);
3211		size_t i=0; search_vec(p->dynv, &i, DT_MIPS_SYMTABNO);
3212		n += i-j;
3213	}
3214	p->lazy = calloc(n, 3*sizeof(size_t));
3215	if (!p->lazy) {
3216		error("Error preparing lazy relocation for %s: %m", p->name);
3217		longjmp(*rtld_fail, 1);
3218	}
3219	p->lazy_next = lazy_head;
3220	lazy_head = p;
3221}
3222
3223static void *dlopen_post(struct dso* p, int mode) {
3224	if (p == NULL) {
3225		return p;
3226	}
3227	bool is_dlclose_debug = false;
3228	if (is_dlclose_debug_enable()) {
3229		is_dlclose_debug = true;
3230	}
3231	p->nr_dlopen++;
3232	if (is_dlclose_debug) {
3233		LD_LOGE("[dlclose]: %{public}s nr_dlopen++ when dlopen %{public}s, nr_dlopen:%{public}d ",
3234				p->name, p->name, p->nr_dlopen);
3235	}
3236	if (p->bfs_built) {
3237		for (int i = 0; p->deps[i]; i++) {
3238			p->deps[i]->nr_dlopen++;
3239			if (is_dlclose_debug) {
3240				LD_LOGE("[dlclose]: %{public}s nr_dlopen++ when dlopen %{public}s, nr_dlopen:%{public}d",
3241						p->deps[i]->name, p->name, p->deps[i]->nr_dlopen);
3242			}
3243			if (mode & RTLD_NODELETE) {
3244				p->deps[i]->flags |= DSO_FLAGS_NODELETE;
3245			}
3246		}
3247	}
3248
3249#ifdef HANDLE_RANDOMIZATION
3250	void *handle = assign_valid_handle(p);
3251	if (handle == NULL) {
3252		LD_LOGE("dlopen_post: generate random handle failed");
3253		do_dlclose(p);
3254	}
3255
3256	return handle;
3257#endif
3258
3259	return p;
3260}
3261
3262static char *dlopen_permitted_list[] =
3263{
3264	"default",
3265	"ndk",
3266};
3267
3268#define PERMITIED_TARGET  "nweb_ns"
3269static bool in_permitted_list(char *caller, char *target)
3270{
3271	for (int i = 0; i < sizeof(dlopen_permitted_list)/sizeof(char*); i++) {
3272		if (strcmp(dlopen_permitted_list[i], caller) == 0) {
3273			return true;
3274		}
3275	}
3276
3277	if (strcmp(PERMITIED_TARGET, target) == 0) {
3278		return true;
3279	}
3280
3281	return false;
3282}
3283
3284static bool is_permitted(const void *caller_addr, char *target)
3285{
3286	struct dso *caller;
3287	ns_t *ns;
3288	caller = (struct dso *)addr2dso((size_t)caller_addr);
3289	if ((caller == NULL) || (caller->namespace == NULL)) {
3290		LD_LOGE("caller ns get error");
3291		return false;
3292	}
3293
3294	ns = caller->namespace;
3295	if (in_permitted_list(ns->ns_name, target) == false) {
3296		LD_LOGE("caller ns: %{public}s have no permission, target is %{public}s", ns->ns_name, target);
3297		return false;
3298	}
3299
3300	return true;
3301}
3302
3303/* Add namespace function.
3304 * Some limitations come from sanitizer:
3305 *  Sanitizer requires this interface to be exposed.
3306 *  Pay attention to call __builtin_return_address in this interface because sanitizer can hook and call this interface.
3307 */
3308void *dlopen_impl(
3309	const char *file, int mode, const char *namespace, const void *caller_addr, const dl_extinfo *extinfo)
3310{
3311	struct dso *volatile p, *orig_tail, *orig_syms_tail, *orig_lazy_head, *next;
3312	struct tls_module *orig_tls_tail;
3313	size_t orig_tls_cnt, orig_tls_offset, orig_tls_align;
3314	size_t i;
3315	int cs;
3316	jmp_buf jb;
3317	struct dso **volatile ctor_queue = 0;
3318	ns_t *ns;
3319	struct dso *caller;
3320	bool reserved_address = false;
3321	bool reserved_address_recursive = false;
3322	struct reserved_address_params reserved_params = {0};
3323#ifdef LOAD_ORDER_RANDOMIZATION
3324	struct loadtasks *tasks = NULL;
3325	struct loadtask *task = NULL;
3326	bool is_task_appended = false;
3327#endif
3328
3329	if (!file) {
3330		LD_LOGD("dlopen_impl file is null, return head.");
3331		return dlopen_post(head, mode);
3332	}
3333
3334	if (extinfo) {
3335		reserved_address_recursive = extinfo->flag & DL_EXT_RESERVED_ADDRESS_RECURSIVE;
3336		if (extinfo->flag & DL_EXT_RESERVED_ADDRESS) {
3337			reserved_address = true;
3338			reserved_params.start_addr = extinfo->reserved_addr;
3339			reserved_params.reserved_size = extinfo->reserved_size;
3340			reserved_params.must_use_reserved = true;
3341			reserved_params.reserved_address_recursive = reserved_address_recursive;
3342		} else if (extinfo->flag & DL_EXT_RESERVED_ADDRESS_HINT) {
3343			reserved_address = true;
3344			reserved_params.start_addr = extinfo->reserved_addr;
3345			reserved_params.reserved_size = extinfo->reserved_size;
3346			reserved_params.must_use_reserved = false;
3347			reserved_params.reserved_address_recursive = reserved_address_recursive;
3348		}
3349	}
3350
3351	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
3352	pthread_rwlock_wrlock(&lock);
3353	__inhibit_ptc();
3354	trace_marker_reset();
3355	trace_marker_begin(HITRACE_TAG_MUSL, "dlopen: ", file);
3356
3357	/* When namespace does not exist, use caller's namespce
3358	 * and when caller does not exist, use default namespce. */
3359	caller = (struct dso *)addr2dso((size_t)caller_addr);
3360	ns = find_ns_by_name(namespace);
3361	if (!ns) ns = ((caller && caller->namespace) ? caller->namespace : get_default_ns());
3362
3363	p = 0;
3364	if (shutting_down) {
3365		error("Cannot dlopen while program is exiting.");
3366		goto end;
3367	}
3368	orig_tls_tail = tls_tail;
3369	orig_tls_cnt = tls_cnt;
3370	orig_tls_offset = tls_offset;
3371	orig_tls_align = tls_align;
3372	orig_lazy_head = lazy_head;
3373	orig_syms_tail = syms_tail;
3374	orig_tail = tail;
3375	noload = mode & RTLD_NOLOAD;
3376
3377	rtld_fail = &jb;
3378	if (setjmp(*rtld_fail)) {
3379		/* Clean up anything new that was (partially) loaded */
3380		revert_syms(orig_syms_tail);
3381		for (p=orig_tail->next; p; p=next) {
3382			next = p->next;
3383			while (p->td_index) {
3384				void *tmp = p->td_index->next;
3385				free(p->td_index);
3386				p->td_index = tmp;
3387			}
3388			free(p->funcdescs);
3389			if (p->rpath != p->rpath_orig)
3390				free(p->rpath);
3391			if (p->deps) {
3392				for (int i = 0; i < p->ndeps_direct; i++) {
3393					remove_dso_parent(p->deps[i], p);
3394				}
3395			}
3396			free(p->deps);
3397			dlclose_ns(p);
3398			unmap_library(p);
3399			if (p->parents) {
3400				free(p->parents);
3401			}
3402			free_reloc_can_search_dso(p);
3403		}
3404		for (p=orig_tail->next; p; p=next) {
3405			next = p->next;
3406			free(p);
3407		}
3408		free(ctor_queue);
3409		ctor_queue = 0;
3410		if (!orig_tls_tail) libc.tls_head = 0;
3411		tls_tail = orig_tls_tail;
3412		if (tls_tail) tls_tail->next = 0;
3413		tls_cnt = orig_tls_cnt;
3414		tls_offset = orig_tls_offset;
3415		tls_align = orig_tls_align;
3416		lazy_head = orig_lazy_head;
3417		tail = orig_tail;
3418		tail->next = 0;
3419		p = 0;
3420		goto end;
3421	} else {
3422#ifdef LOAD_ORDER_RANDOMIZATION
3423		tasks = create_loadtasks();
3424		if (!tasks) {
3425			LD_LOGE("dlopen_impl create loadtasks failed");
3426			goto end;
3427		}
3428		task = create_loadtask(file, head, ns, true);
3429		if (!task) {
3430			LD_LOGE("dlopen_impl create loadtask failed");
3431			goto end;
3432		}
3433		trace_marker_begin(HITRACE_TAG_MUSL, "loading: entry so", file);
3434		if (!load_library_header(task)) {
3435			error(noload ?
3436				"Library %s is not already loaded" :
3437				"Error loading shared library %s: %m",
3438				file);
3439			LD_LOGE("dlopen_impl load library header failed for %{public}s", task->name);
3440			trace_marker_end(HITRACE_TAG_MUSL); // "loading: entry so" trace end.
3441			goto end;
3442		}
3443		if (reserved_address) {
3444			reserved_params.target = task->p;
3445		}
3446	}
3447	if (!task->p) {
3448		LD_LOGE("dlopen_impl load library failed for %{public}s", task->name);
3449		error(noload ?
3450			"Library %s is not already loaded" :
3451			"Error loading shared library %s: %m",
3452			file);
3453		trace_marker_end(HITRACE_TAG_MUSL); // "loading: entry so" trace end.
3454		goto end;
3455	}
3456	if (!task->isloaded) {
3457		is_task_appended = append_loadtasks(tasks, task);
3458	}
3459	preload_deps(task->p, tasks);
3460	unmap_preloaded_sections(tasks);
3461	if (!reserved_address_recursive) {
3462		shuffle_loadtasks(tasks);
3463	}
3464	run_loadtasks(tasks, reserved_address ? &reserved_params : NULL);
3465	p = task->p;
3466	if (!task->isloaded) {
3467		assign_tls(p);
3468	}
3469	if (!is_task_appended) {
3470		free_task(task);
3471		task = NULL;
3472	}
3473	free_loadtasks(tasks);
3474	tasks = NULL;
3475#else
3476		trace_marker_begin(HITRACE_TAG_MUSL, "loading: entry so", file);
3477		p = load_library(file, head, ns, true, reserved_address ? &reserved_params : NULL);
3478	}
3479
3480	if (!p) {
3481		error(noload ?
3482			"Library %s is not already loaded" :
3483			"Error loading shared library %s: %m",
3484			file);
3485		trace_marker_end(HITRACE_TAG_MUSL); // "loading: entry so" trace end.
3486		goto end;
3487	}
3488	/* First load handling */
3489	load_deps(p, reserved_address && reserved_address_recursive ? &reserved_params : NULL);
3490#endif
3491	trace_marker_end(HITRACE_TAG_MUSL); // "loading: entry so" trace end.
3492	extend_bfs_deps(p);
3493	pthread_mutex_lock(&init_fini_lock);
3494	int constructed = p->constructed;
3495	pthread_mutex_unlock(&init_fini_lock);
3496	if (!constructed) ctor_queue = queue_ctors(p);
3497	if (!p->relocated && (mode & RTLD_LAZY)) {
3498		prepare_lazy(p);
3499		for (i=0; p->deps[i]; i++)
3500			if (!p->deps[i]->relocated)
3501				prepare_lazy(p->deps[i]);
3502	}
3503	if (!p->relocated || (mode & RTLD_GLOBAL)) {
3504		/* Make new symbols global, at least temporarily, so we can do
3505		 * relocations. If not RTLD_GLOBAL, this is reverted below. */
3506		add_syms(p);
3507		/* Set is_reloc_head_so_dep to true for all direct and indirect dependent sos of p, including p self. */
3508		p->is_reloc_head_so_dep = true;
3509		for (i=0; p->deps[i]; i++) {
3510			p->deps[i]->is_reloc_head_so_dep = true;
3511			add_syms(p->deps[i]);
3512		}
3513	}
3514	struct dso *reloc_head_so = p;
3515	trace_marker_begin(HITRACE_TAG_MUSL, "linking: entry so", p->name);
3516	if (!p->relocated) {
3517		reloc_all(p, extinfo);
3518	}
3519	trace_marker_end(HITRACE_TAG_MUSL);
3520	reloc_head_so->is_reloc_head_so_dep = false;
3521	for (size_t i=0; reloc_head_so->deps[i]; i++) {
3522		reloc_head_so->deps[i]->is_reloc_head_so_dep = false;
3523	}
3524
3525	/* If RTLD_GLOBAL was not specified, undo any new additions
3526	 * to the global symbol table. This is a nop if the library was
3527	 * previously loaded and already global. */
3528	if (!(mode & RTLD_GLOBAL))
3529		revert_syms(orig_syms_tail);
3530
3531	/* Processing of deferred lazy relocations must not happen until
3532	 * the new libraries are committed; otherwise we could end up with
3533	 * relocations resolved to symbol definitions that get removed. */
3534	redo_lazy_relocs();
3535
3536	if (map_dso_to_cfi_shadow(p) == CFI_FAILED) {
3537		error("[%s] map_dso_to_cfi_shadow failed: %m", __FUNCTION__);
3538		longjmp(*rtld_fail, 1);
3539	}
3540
3541	if (mode & RTLD_NODELETE) {
3542		p->flags |= DSO_FLAGS_NODELETE;
3543	}
3544
3545	update_tls_size();
3546	if (tls_cnt != orig_tls_cnt)
3547		install_new_tls();
3548
3549	if (orig_tail != tail) {
3550		notify_addition_to_debugger(orig_tail->next);
3551	}
3552
3553	orig_tail = tail;
3554
3555	p = dlopen_post(p, mode);
3556end:
3557#ifdef LOAD_ORDER_RANDOMIZATION
3558	if (!is_task_appended) {
3559		free_task(task);
3560	}
3561	free_loadtasks(tasks);
3562#endif
3563	__release_ptc();
3564	if (p) gencnt++;
3565	pthread_rwlock_unlock(&lock);
3566	if (ctor_queue) {
3567		do_init_fini(ctor_queue);
3568		free(ctor_queue);
3569	}
3570	pthread_setcancelstate(cs, 0);
3571	trace_marker_end(HITRACE_TAG_MUSL); // "dlopen: " trace end.
3572	return p;
3573}
3574
3575void *dlopen(const char *file, int mode)
3576{
3577	const void *caller_addr = __builtin_return_address(0);
3578	musl_log_reset();
3579	ld_log_reset();
3580	LD_LOGI("dlopen file:%{public}s, mode:%{public}x ,caller_addr:%{public}p .", file, mode, caller_addr);
3581	return dlopen_impl(file, mode, NULL, caller_addr, NULL);
3582}
3583
3584void dlns_init(Dl_namespace *dlns, const char *name)
3585{
3586	if (!dlns) {
3587		return;
3588	}
3589	if (!name) {
3590		dlns->name[0] = 0;
3591		return;
3592	}
3593
3594	const void *caller_addr = __builtin_return_address(0);
3595	if (is_permitted(caller_addr, name) == false) {
3596		return;
3597	}
3598
3599	snprintf(dlns->name, sizeof dlns->name, name);
3600	LD_LOGI("dlns_init dlns->name:%{public}s .", dlns->name);
3601}
3602
3603int dlns_get(const char *name, Dl_namespace *dlns)
3604{
3605	if (!dlns) {
3606		LD_LOGE("dlns_get dlns is null.");
3607		return EINVAL;
3608	}
3609	int ret = 0;
3610	ns_t *ns = NULL;
3611	pthread_rwlock_rdlock(&lock);
3612	if (!name) {
3613		struct dso *caller;
3614		const void *caller_addr = __builtin_return_address(0);
3615		caller = (struct dso *)addr2dso((size_t)caller_addr);
3616		ns = ((caller && caller->namespace) ? caller->namespace : get_default_ns());
3617		(void)snprintf(dlns->name, sizeof dlns->name, ns->ns_name);
3618		LD_LOGI("dlns_get name is null, current dlns dlns->name:%{public}s.", dlns->name);
3619	} else {
3620		ns = find_ns_by_name(name);
3621		if (ns) {
3622			(void)snprintf(dlns->name, sizeof dlns->name, ns->ns_name);
3623			LD_LOGI("dlns_get found ns, current dlns dlns->name:%{public}s.", dlns->name);
3624		} else {
3625			LD_LOGI("dlns_get not found ns! name:%{public}s.", name);
3626			ret = ENOKEY;
3627		}
3628	}
3629	pthread_rwlock_unlock(&lock);
3630	return ret;
3631}
3632
3633void *dlopen_ns(Dl_namespace *dlns, const char *file, int mode)
3634{
3635	const void *caller_addr = __builtin_return_address(0);
3636	if (is_permitted(caller_addr, dlns->name) == false) {
3637		return NULL;
3638	}
3639
3640	musl_log_reset();
3641	ld_log_reset();
3642	LD_LOGI("dlopen_ns file:%{public}s, mode:%{public}x , caller_addr:%{public}p , dlns->name:%{public}s.",
3643		file,
3644		mode,
3645		caller_addr,
3646		dlns ? dlns->name : "NULL");
3647	return dlopen_impl(file, mode, dlns->name, caller_addr, NULL);
3648}
3649
3650void *dlopen_ns_ext(Dl_namespace *dlns, const char *file, int mode, const dl_extinfo *extinfo)
3651{
3652	const void *caller_addr = __builtin_return_address(0);
3653	if (is_permitted(caller_addr, dlns->name) == false) {
3654		return NULL;
3655	}
3656
3657	musl_log_reset();
3658	ld_log_reset();
3659	LD_LOGI("dlopen_ns_ext file:%{public}s, mode:%{public}x , caller_addr:%{public}p , "
3660			"dlns->name:%{public}s. , extinfo->flag:%{public}x",
3661		file,
3662		mode,
3663		caller_addr,
3664		dlns->name,
3665		extinfo ? extinfo->flag : 0);
3666	return dlopen_impl(file, mode, dlns->name, caller_addr, extinfo);
3667}
3668
3669int dlns_create2(Dl_namespace *dlns, const char *lib_path, int flags)
3670{
3671	if (!dlns) {
3672		LD_LOGE("dlns_create2 dlns is null.");
3673		return EINVAL;
3674	}
3675	ns_t *ns;
3676
3677	pthread_rwlock_wrlock(&lock);
3678	const void *caller_addr = __builtin_return_address(0);
3679	if (is_permitted(caller_addr, dlns->name) == false) {
3680		pthread_rwlock_unlock(&lock);
3681		return EPERM;
3682	}
3683
3684	ns = find_ns_by_name(dlns->name);
3685	if (ns) {
3686		LD_LOGE("dlns_create2 ns is exist.");
3687		pthread_rwlock_unlock(&lock);
3688		return EEXIST;
3689	}
3690	ns = ns_alloc();
3691	if (!ns) {
3692		LD_LOGE("dlns_create2 no memery.");
3693		pthread_rwlock_unlock(&lock);
3694		return ENOMEM;
3695	}
3696	ns_set_name(ns, dlns->name);
3697	ns_set_flag(ns, flags);
3698	ns_add_dso(ns, get_default_ns()->ns_dsos->dsos[0]); /* add main app to this namespace*/
3699	nslist_add_ns(ns); /* add ns to list*/
3700	ns_set_lib_paths(ns, lib_path);
3701
3702	if ((flags & CREATE_INHERIT_DEFAULT) != 0) {
3703		ns_add_inherit(ns, get_default_ns(), NULL);
3704	}
3705
3706	if ((flags & CREATE_INHERIT_CURRENT) != 0) {
3707		struct dso *caller;
3708		caller_addr = __builtin_return_address(0);
3709		caller = (struct dso *)addr2dso((size_t)caller_addr);
3710		if (caller && caller->namespace) {
3711			ns_add_inherit(ns, caller->namespace, NULL);
3712		}
3713	}
3714
3715	LD_LOGI("dlns_create2:"
3716			"ns_name: %{public}s ,"
3717			"separated:%{public}d ,"
3718			"lib_paths:%{public}s ",
3719			ns->ns_name, ns->separated, ns->lib_paths);
3720	pthread_rwlock_unlock(&lock);
3721
3722	return 0;
3723}
3724
3725int dlns_create(Dl_namespace *dlns, const char *lib_path)
3726{
3727	LD_LOGI("dlns_create lib_paths:%{public}s", lib_path);
3728	return dlns_create2(dlns, lib_path, CREATE_INHERIT_DEFAULT);
3729}
3730
3731int dlns_inherit(Dl_namespace *dlns, Dl_namespace *inherited, const char *shared_libs)
3732{
3733	if (!dlns || !inherited) {
3734		LD_LOGE("dlns_inherit dlns or inherited is null.");
3735		return EINVAL;
3736	}
3737
3738	pthread_rwlock_wrlock(&lock);
3739	const void *caller_addr = __builtin_return_address(0);
3740	if (is_permitted(caller_addr, dlns->name) == false) {
3741		pthread_rwlock_unlock(&lock);
3742		return EPERM;
3743	}
3744
3745	ns_t* ns = find_ns_by_name(dlns->name);
3746	ns_t* ns_inherited = find_ns_by_name(inherited->name);
3747	if (!ns || !ns_inherited) {
3748		LD_LOGE("dlns_inherit ns or ns_inherited is not found.");
3749		pthread_rwlock_unlock(&lock);
3750		return ENOKEY;
3751	}
3752	ns_add_inherit(ns, ns_inherited, shared_libs);
3753	pthread_rwlock_unlock(&lock);
3754
3755	return 0;
3756}
3757
3758static void dlclose_ns(struct dso *p)
3759{
3760	if (!p) return;
3761	ns_t * ns = p->namespace;
3762	if (!ns||!ns->ns_dsos) return;
3763	for (size_t i=0; i<ns->ns_dsos->num; i++) {
3764		if (p == ns->ns_dsos->dsos[i]) {
3765			for (size_t j=i+1; j<ns->ns_dsos->num; j++) {
3766				ns->ns_dsos->dsos[j-1] = ns->ns_dsos->dsos[j];
3767			}
3768			ns->ns_dsos->num--;
3769			return;
3770		}
3771	}
3772}
3773
3774hidden int __dl_invalid_handle(void *h)
3775{
3776	struct dso *p;
3777	for (p=head; p; p=p->next) if (h==p) return 0;
3778	error("Invalid library handle %p", (void *)h);
3779	return 1;
3780}
3781
3782void *addr2dso(size_t a)
3783{
3784	struct dso *p;
3785	size_t i;
3786	for (p=head; p; p=p->next) {
3787		if (a < p->map || a - (size_t)p->map >= p->map_len) continue;
3788		Phdr *ph = p->phdr;
3789		size_t phcnt = p->phnum;
3790		size_t entsz = p->phentsize;
3791		size_t base = (size_t)p->base;
3792		for (; phcnt--; ph=(void *)((char *)ph+entsz)) {
3793			if (ph->p_type != PT_LOAD) continue;
3794			if (a-base-ph->p_vaddr < ph->p_memsz)
3795				return p;
3796		}
3797		if (a-(size_t)p->map < p->map_len)
3798			return 0;
3799	}
3800	return 0;
3801}
3802
3803static void *do_dlsym(struct dso *p, const char *s, const char *v, void *ra)
3804{
3805	int use_deps = 0;
3806	bool ra2dso = false;
3807	ns_t *ns = NULL;
3808	struct dso *caller = NULL;
3809	if (p == head || p == RTLD_DEFAULT) {
3810		p = head;
3811		ra2dso = true;
3812	} else if (p == RTLD_NEXT) {
3813		p = addr2dso((size_t)ra);
3814		if (!p) p=head;
3815		p = p->next;
3816		ra2dso = true;
3817#ifndef HANDLE_RANDOMIZATION
3818	} else if (__dl_invalid_handle(p)) {
3819		return 0;
3820#endif
3821	} else {
3822		use_deps = 1;
3823		ns = p->namespace;
3824	}
3825	if (ra2dso) {
3826		caller = (struct dso *)addr2dso((size_t)ra);
3827		if (caller && caller->namespace) {
3828			ns = caller->namespace;
3829		}
3830	}
3831	trace_marker_begin(HITRACE_TAG_MUSL, "dlsym: ", (s == NULL ? "(NULL)" : s));
3832	struct verinfo verinfo = { .s = s, .v = v, .use_vna_hash = false };
3833	struct symdef def = use_deps ? find_sym_by_deps(p, &verinfo, 0, ns) :
3834		find_sym2(p, &verinfo, 0, use_deps, ns);
3835	trace_marker_end(HITRACE_TAG_MUSL);
3836	if (!def.sym) {
3837		LD_LOGW("do_dlsym failed: symbol not found. so=%{public}s s=%{public}s v=%{public}s",
3838			(p == NULL ? "NULL" : p->name), s, v);
3839		error("do_dlsym failed: Symbol not found: %s, version: %s so=%s",
3840			s, strlen(v) > 0 ? v : "null", (p == NULL ? "NULL" : p->name));
3841		return 0;
3842	}
3843	if ((def.sym->st_info&0xf) == STT_TLS)
3844		return __tls_get_addr((tls_mod_off_t []){def.dso->tls_id, def.sym->st_value-DTP_OFFSET});
3845	if (DL_FDPIC && (def.sym->st_info&0xf) == STT_FUNC)
3846		return def.dso->funcdescs + (def.sym - def.dso->syms);
3847	return laddr(def.dso, def.sym->st_value);
3848}
3849
3850extern int invalidate_exit_funcs(struct dso *p);
3851
3852static int so_can_unload(struct dso *p, int check_flag)
3853{
3854	if ((check_flag & UNLOAD_COMMON_CHECK) != 0) {
3855		if (__dl_invalid_handle(p)) {
3856			LD_LOGE("[dlclose]: invalid handle %{public}p", p);
3857			error("[dlclose]: Handle is invalid.");
3858			return 0;
3859		}
3860
3861		if (!p->by_dlopen) {
3862			LD_LOGD("[dlclose]: skip unload %{public}s because it's not loaded by dlopen", p->name);
3863			return 0;
3864		}
3865
3866		/* dso is marked  as RTLD_NODELETE library, do nothing here. */
3867		if ((p->flags & DSO_FLAGS_NODELETE) != 0) {
3868			LD_LOGD("[dlclose]: skip unload %{public}s because flags is RTLD_NODELETE", p->name);
3869			return 0;
3870		}
3871	}
3872
3873	if ((check_flag & UNLOAD_NR_DLOPEN_CHECK) != 0) {
3874		if (p->nr_dlopen > 0) {
3875			LD_LOGD("[dlclose]: skip unload %{public}s because nr_dlopen=%{public}d > 0", p->name, p->nr_dlopen);
3876			return 0;
3877		}
3878	}
3879
3880	return 1;
3881}
3882
3883static int dlclose_post(struct dso *p)
3884{
3885	if (p == NULL) {
3886		return -1;
3887	}
3888#ifdef ENABLE_HWASAN
3889		if (libc.unload_hook) {
3890			libc.unload_hook((unsigned long int)p->base, p->phdr, p->phnum);
3891		}
3892#endif
3893	unmap_library(p);
3894	if (p->parents) {
3895		free(p->parents);
3896	}
3897	free_reloc_can_search_dso(p);
3898	if (p->tls.size == 0) {
3899		free(p);
3900	}
3901
3902	return 0;
3903}
3904
3905static int dlclose_impl(struct dso *p)
3906{
3907	struct dso *d;
3908
3909	trace_marker_reset();
3910	trace_marker_begin(HITRACE_TAG_MUSL, "dlclose", p->name);
3911
3912	/* remove dso symbols from global list */
3913	if (p->syms_next) {
3914		for (d = head; d->syms_next != p; d = d->syms_next)
3915			; /* NOP */
3916		d->syms_next = p->syms_next;
3917	} else if (p == syms_tail) {
3918		for (d = head; d->syms_next != p; d = d->syms_next)
3919			; /* NOP */
3920		d->syms_next = NULL;
3921		syms_tail = d;
3922	}
3923
3924	/* remove dso from lazy list if needed */
3925	if (p == lazy_head) {
3926		lazy_head = p->lazy_next;
3927	} else if (p->lazy_next) {
3928		for (d = lazy_head; d->lazy_next != p; d = d->lazy_next)
3929			; /* NOP */
3930		d->lazy_next = p->lazy_next;
3931	}
3932
3933	pthread_mutex_lock(&init_fini_lock);
3934	/* remove dso from fini list */
3935	if (p == fini_head) {
3936		fini_head = p->fini_next;
3937	} else if (p->fini_next) {
3938		for (d = fini_head; d->fini_next != p; d = d->fini_next)
3939			; /* NOP */
3940		d->fini_next = p->fini_next;
3941	}
3942	pthread_mutex_unlock(&init_fini_lock);
3943
3944	/* empty tls image */
3945	if (p->tls.size != 0) {
3946		p->tls.image = NULL;
3947	}
3948
3949	/* remove dso from global dso list */
3950	if (p == tail) {
3951		tail = p->prev;
3952		tail->next = NULL;
3953	} else {
3954		p->next->prev = p->prev;
3955		p->prev->next = p->next;
3956	}
3957
3958	/* remove dso from namespace */
3959	dlclose_ns(p);
3960
3961	/* */
3962	void* handle = find_handle_by_dso(p);
3963	if (handle) {
3964		remove_handle_node(handle);
3965	}
3966
3967	/* after destruct, invalidate atexit funcs which belong to this dso */
3968#if (defined(FEATURE_ATEXIT_CB_PROTECT))
3969	invalidate_exit_funcs(p);
3970#endif
3971
3972	notify_remove_to_debugger(p);
3973
3974	unmap_dso_from_cfi_shadow(p);
3975
3976	if (p->lazy != NULL)
3977		free(p->lazy);
3978	if (p->deps != no_deps)
3979		free(p->deps);
3980
3981	trace_marker_end(HITRACE_TAG_MUSL);
3982
3983	return 0;
3984}
3985
3986static int do_dlclose(struct dso *p)
3987{
3988	struct dso_entry *ef = NULL;
3989	struct dso_entry *ef_tmp = NULL;
3990	size_t n;
3991	int unload_check_result;
3992	TAILQ_HEAD(unload_queue, dso_entry) unload_queue;
3993	TAILQ_HEAD(need_unload_queue, dso_entry) need_unload_queue;
3994	unload_check_result = so_can_unload(p, UNLOAD_COMMON_CHECK);
3995	if (unload_check_result != 1) {
3996		return unload_check_result;
3997	}
3998	// Unconditionally subtract 1 because unconditionally add 1 at dlopen_post.
3999	if (p->nr_dlopen > 0) {
4000		--(p->nr_dlopen);
4001	} else {
4002		LD_LOGE("[dlclose]: number of dlopen and dlclose of %{public}s doesn't match when dlclose %{public}s",
4003		        p->name, p->name);
4004		return 0;
4005	}
4006
4007	if (p->bfs_built) {
4008		for (int i = 0; p->deps[i]; i++) {
4009			if (p->deps[i]->nr_dlopen > 0) {
4010				p->deps[i]->nr_dlopen--;
4011			} else {
4012				LD_LOGE("[dlclose]: number of dlopen and dlclose of %{public}s doesn't match when dlclose %{public}s",
4013						p->deps[i]->name, p->name);
4014				return 0;
4015			}
4016		}
4017	}
4018	unload_check_result = so_can_unload(p, UNLOAD_NR_DLOPEN_CHECK);
4019	if (unload_check_result != 1) {
4020		return unload_check_result;
4021	}
4022	TAILQ_INIT(&unload_queue);
4023	TAILQ_INIT(&need_unload_queue);
4024	struct dso_entry *start_entry = (struct dso_entry *)malloc(sizeof(struct dso_entry));
4025	start_entry->dso = p;
4026	TAILQ_INSERT_TAIL(&unload_queue, start_entry, entries);
4027
4028	while (!TAILQ_EMPTY(&unload_queue)) {
4029		struct dso_entry *ecur = TAILQ_FIRST(&unload_queue);
4030		struct dso *cur = ecur->dso;
4031		TAILQ_REMOVE(&unload_queue, ecur, entries);
4032		bool already_in_need_unload_queue = false;
4033		TAILQ_FOREACH(ef, &need_unload_queue, entries) {
4034			if (ef->dso == cur) {
4035				already_in_need_unload_queue = true;
4036				break;
4037			}
4038		}
4039		if (already_in_need_unload_queue) {
4040			continue;
4041		}
4042		TAILQ_INSERT_TAIL(&need_unload_queue, ecur, entries);
4043		for (int i = 0; i < cur->ndeps_direct; i++) {
4044			remove_dso_parent(cur->deps[i], cur);
4045			if ((cur->deps[i]->parents_count == 0) && (so_can_unload(cur->deps[i], UNLOAD_ALL_CHECK) == 1)) {
4046				bool already_in_unload_queue = false;
4047				TAILQ_FOREACH(ef, &unload_queue, entries) {
4048					if (ef->dso == cur->deps[i]) {
4049						already_in_unload_queue = true;
4050						break;
4051					}
4052				}
4053				if (already_in_unload_queue) {
4054					continue;
4055				}
4056
4057				struct dso_entry *edeps = (struct dso_entry *)malloc(sizeof(struct dso_entry));
4058				edeps->dso = cur->deps[i];
4059				TAILQ_INSERT_TAIL(&unload_queue, edeps, entries);
4060			}
4061		} /* for */
4062	} /* while */
4063
4064	if (is_dlclose_debug_enable()) {
4065		TAILQ_FOREACH(ef, &need_unload_queue, entries) {
4066			LD_LOGE("[dlclose]: unload %{public}s succeed when dlclose %{public}s", ef->dso->name, p->name);
4067		}
4068		for (size_t deps_num = 0; p->deps[deps_num]; deps_num++) {
4069			bool ready_to_unload = false;
4070			TAILQ_FOREACH(ef, &need_unload_queue, entries) {
4071				if (ef->dso == p->deps[deps_num]) {
4072					ready_to_unload = true;
4073					break;
4074				}
4075			}
4076			if (!ready_to_unload) {
4077				LD_LOGE("[dlclose]: unload %{public}s failed when dlclose %{public}s,"
4078				        "nr_dlopen:%{public}d, by_dlopen:%{public}d, parents_count:%{public}d",
4079						p->deps[deps_num]->name, p->name, p->deps[deps_num]->nr_dlopen,
4080						p->deps[deps_num]->by_dlopen, p->deps[deps_num]->parents_count);
4081			}
4082		}
4083	}
4084
4085	TAILQ_FOREACH(ef, &need_unload_queue, entries) {
4086		dlclose_impl(ef->dso);
4087	}
4088
4089	TAILQ_FOREACH(ef, &need_unload_queue, entries) {
4090		/* call destructors if needed */
4091		pthread_mutex_lock(&init_fini_lock);
4092		int constructed = ef->dso->constructed;
4093		pthread_mutex_unlock(&init_fini_lock);
4094
4095		if (constructed) {
4096			size_t dyn[DYN_CNT];
4097			decode_vec(ef->dso->dynv, dyn, DYN_CNT);
4098			if (dyn[0] & (1<<DT_FINI_ARRAY)) {
4099				n = dyn[DT_FINI_ARRAYSZ] / sizeof(size_t);
4100				size_t *fn = (size_t *)laddr(ef->dso, dyn[DT_FINI_ARRAY]) + n;
4101				trace_marker_begin(HITRACE_TAG_MUSL, "calling destructors:", ef->dso->name);
4102
4103				pthread_rwlock_unlock(&lock);
4104				while (n--)
4105					((void (*)(void))*--fn)();
4106				pthread_rwlock_wrlock(&lock);
4107
4108				trace_marker_end(HITRACE_TAG_MUSL);
4109			}
4110			pthread_mutex_lock(&init_fini_lock);
4111			ef->dso->constructed = 0;
4112			pthread_mutex_unlock(&init_fini_lock);
4113		}
4114	}
4115	// Unload all sos at the end because weak symbol may cause later unloaded so to access the previous so's function.
4116	TAILQ_FOREACH(ef, &need_unload_queue, entries) {
4117		dlclose_post(ef->dso);
4118	}
4119	// Free dso_entry.
4120	TAILQ_FOREACH_SAFE(ef, &need_unload_queue, entries, ef_tmp) {
4121		if (ef) {
4122			free(ef);
4123		}
4124	}
4125
4126	return 0;
4127}
4128
4129hidden int __dlclose(void *p)
4130{
4131	int rc;
4132	pthread_rwlock_wrlock(&lock);
4133	if (shutting_down) {
4134		error("Cannot dlclose while program is exiting.");
4135		pthread_rwlock_unlock(&lock);
4136		return -1;
4137	}
4138#ifdef HANDLE_RANDOMIZATION
4139	struct dso *dso = find_dso_by_handle(p);
4140	if (dso == NULL) {
4141		errno = EINVAL;
4142		error("Handle is invalid.");
4143		LD_LOGE("Handle is not find.");
4144		pthread_rwlock_unlock(&lock);
4145		return -1;
4146	}
4147	rc = do_dlclose(dso);
4148#else
4149	rc = do_dlclose(p);
4150#endif
4151	pthread_rwlock_unlock(&lock);
4152	return rc;
4153}
4154
4155static inline int sym_is_matched(const Sym* sym, size_t addr_offset_so) {
4156	return sym->st_value &&
4157		(1<<(sym->st_info&0xf) != STT_TLS) &&
4158		(addr_offset_so >= sym->st_value) &&
4159		(addr_offset_so < sym->st_value + sym->st_size);
4160}
4161
4162static inline Sym* find_addr_by_elf(size_t addr_offset_so, struct dso *p) {
4163	uint32_t nsym = p->hashtab[1];
4164	Sym *sym = p->syms;
4165	for (; nsym; nsym--, sym++) {
4166		if (sym_is_matched(sym, addr_offset_so)) {
4167			return sym;
4168		}
4169	}
4170
4171	return NULL;
4172}
4173
4174static inline Sym* find_addr_by_gnu(size_t addr_offset_so, struct dso *p) {
4175
4176	size_t i, nsym, first_hash_sym_index;
4177	uint32_t *hashval;
4178	Sym *sym_tab = p->syms;
4179	uint32_t *buckets= p->ghashtab + 4 + (p->ghashtab[2]*sizeof(size_t)/4);
4180	// Points to the first defined symbol, all symbols before it are undefined.
4181	first_hash_sym_index = buckets[0];
4182	Sym *sym = &sym_tab[first_hash_sym_index];
4183
4184	// Get the location pointed by the last bucket.
4185	for (i = nsym = 0; i < p->ghashtab[0]; i++) {
4186		if (buckets[i] > nsym)
4187			nsym = buckets[i];
4188	}
4189
4190	for (i = first_hash_sym_index; i < nsym; i++) {
4191		if (sym_is_matched(sym, addr_offset_so)) {
4192			return sym;
4193		}
4194		sym++;
4195	}
4196
4197	// Start traversing the hash list from the position pointed to by the last bucket.
4198	if (nsym) {
4199		hashval = buckets + p->ghashtab[0] + (nsym - p->ghashtab[1]);
4200		do {
4201			nsym++;
4202			if (sym_is_matched(sym, addr_offset_so)) {
4203				return sym;
4204			}
4205			sym++;
4206		}
4207		while (!(*hashval++ & 1));
4208	}
4209
4210	return NULL;
4211}
4212
4213
4214int dladdr(const void *addr_arg, Dl_info *info)
4215{
4216	size_t addr = (size_t)addr_arg;
4217	struct dso *p;
4218	Sym *match_sym = NULL;
4219	char *strings;
4220
4221	pthread_rwlock_rdlock(&lock);
4222	p = addr2dso(addr);
4223	pthread_rwlock_unlock(&lock);
4224
4225	if (!p) return 0;
4226
4227	strings = p->strings;
4228	size_t addr_offset_so = addr - (size_t)p->base;
4229
4230	info->dli_fname = p->name;
4231	info->dli_fbase = p->map;
4232
4233	if (p->ghashtab) {
4234		match_sym = find_addr_by_gnu(addr_offset_so, p);
4235
4236	} else {
4237		match_sym = find_addr_by_elf(addr_offset_so, p);
4238	}
4239
4240	if (!match_sym) {
4241		info->dli_sname = 0;
4242		info->dli_saddr = 0;
4243		return 1;
4244	}
4245	info->dli_sname = strings + match_sym->st_name;
4246	info->dli_saddr = (void *)laddr(p, match_sym->st_value);
4247	return 1;
4248}
4249
4250hidden void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra)
4251{
4252	void *res;
4253	pthread_rwlock_rdlock(&lock);
4254#ifdef HANDLE_RANDOMIZATION
4255	if ((p != RTLD_DEFAULT) && (p != RTLD_NEXT)) {
4256		struct dso *dso = find_dso_by_handle(p);
4257		if (dso == NULL) {
4258			pthread_rwlock_unlock(&lock);
4259			return 0;
4260		}
4261		res = do_dlsym(dso, s, "", ra);
4262	} else {
4263		res = do_dlsym(p, s, "", ra);
4264	}
4265#else
4266	res = do_dlsym(p, s, "", ra);
4267#endif
4268	pthread_rwlock_unlock(&lock);
4269	return res;
4270}
4271
4272hidden void *__dlvsym(void *restrict p, const char *restrict s, const char *restrict v, void *restrict ra)
4273{
4274	void *res;
4275	pthread_rwlock_rdlock(&lock);
4276#ifdef HANDLE_RANDOMIZATION
4277	if ((p != RTLD_DEFAULT) && (p != RTLD_NEXT)) {
4278		struct dso *dso = find_dso_by_handle(p);
4279		if (dso == NULL) {
4280			pthread_rwlock_unlock(&lock);
4281			return 0;
4282		}
4283		res = do_dlsym(dso, s, v, ra);
4284	} else {
4285		res = do_dlsym(p, s, v, ra);
4286	}
4287#else
4288	res = do_dlsym(p, s, v, ra);
4289#endif
4290	pthread_rwlock_unlock(&lock);
4291	return res;
4292}
4293
4294hidden void *__dlsym_redir_time64(void *restrict p, const char *restrict s, void *restrict ra)
4295{
4296#if _REDIR_TIME64
4297	const char *suffix, *suffix2 = "";
4298	char redir[36];
4299
4300	/* Map the symbol name to a time64 version of itself according to the
4301	 * pattern used for naming the redirected time64 symbols. */
4302	size_t l = strnlen(s, sizeof redir);
4303	if (l<4 || l==sizeof redir) goto no_redir;
4304	if (s[l-2]=='_' && s[l-1]=='r') {
4305		l -= 2;
4306		suffix2 = s+l;
4307	}
4308	if (l<4) goto no_redir;
4309	if (!strcmp(s+l-4, "time")) suffix = "64";
4310	else suffix = "_time64";
4311
4312	/* Use the presence of the remapped symbol name in libc to determine
4313	 * whether it's one that requires time64 redirection; replace if so. */
4314	snprintf(redir, sizeof redir, "__%.*s%s%s", (int)l, s, suffix, suffix2);
4315	if (find_sym(&ldso, redir, 1).sym) s = redir;
4316no_redir:
4317#endif
4318	return __dlsym(p, s, ra);
4319}
4320
4321int dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data)
4322{
4323	struct dso *current;
4324	struct dl_phdr_info info;
4325	int ret = 0;
4326	for(current = head; current;) {
4327		info.dlpi_addr      = (uintptr_t)current->base;
4328		info.dlpi_name      = current->name;
4329		info.dlpi_phdr      = current->phdr;
4330		info.dlpi_phnum     = current->phnum;
4331		info.dlpi_adds      = gencnt;
4332		info.dlpi_subs      = 0;
4333		info.dlpi_tls_modid = current->tls_id;
4334		info.dlpi_tls_data = !current->tls_id ? 0 :
4335			__tls_get_addr((tls_mod_off_t[]){current->tls_id,0});
4336
4337		ret = (callback)(&info, sizeof (info), data);
4338
4339		if (ret != 0) break;
4340
4341		pthread_rwlock_rdlock(&lock);
4342		current = current->next;
4343		pthread_rwlock_unlock(&lock);
4344	}
4345	return ret;
4346}
4347
4348static void error(const char *fmt, ...)
4349{
4350	va_list ap;
4351	va_start(ap, fmt);
4352	if (!runtime) {
4353		vdprintf(2, fmt, ap);
4354		dprintf(2, "\n");
4355		ldso_fail = 1;
4356		va_end(ap);
4357		return;
4358	}
4359	__dl_vseterr(fmt, ap);
4360	va_end(ap);
4361}
4362
4363int dlns_set_namespace_lib_path(const char * name, const char * lib_path)
4364{
4365	if (!name || !lib_path) {
4366		LD_LOGE("dlns_set_namespace_lib_path name or lib_path is null.");
4367		return EINVAL;
4368	}
4369
4370	pthread_rwlock_wrlock(&lock);
4371	const void *caller_addr = __builtin_return_address(0);
4372	if (is_permitted(caller_addr, name) == false) {
4373		pthread_rwlock_unlock(&lock);
4374		return EPERM;
4375	}
4376
4377	ns_t* ns = find_ns_by_name(name);
4378	if (!ns) {
4379		pthread_rwlock_unlock(&lock);
4380		LD_LOGE("dlns_set_namespace_lib_path fail, input ns name : [%{public}s] is not found.", name);
4381		return ENOKEY;
4382	}
4383
4384	ns_set_lib_paths(ns, lib_path);
4385	pthread_rwlock_unlock(&lock);
4386	return 0;
4387}
4388
4389int dlns_set_namespace_separated(const char * name, const bool separated)
4390{
4391	if (!name) {
4392		LD_LOGE("dlns_set_namespace_separated name  is null.");
4393		return EINVAL;
4394	}
4395
4396	pthread_rwlock_wrlock(&lock);
4397	const void *caller_addr = __builtin_return_address(0);
4398	if (is_permitted(caller_addr, name) == false) {
4399		pthread_rwlock_unlock(&lock);
4400		return EPERM;
4401	}
4402
4403	ns_t* ns = find_ns_by_name(name);
4404	if (!ns) {
4405		pthread_rwlock_unlock(&lock);
4406		LD_LOGE("dlns_set_namespace_separated fail, input ns name : [%{public}s] is not found.", name);
4407		return ENOKEY;
4408	}
4409
4410	ns_set_separated(ns, separated);
4411	pthread_rwlock_unlock(&lock);
4412	return 0;
4413}
4414
4415int dlns_set_namespace_permitted_paths(const char * name, const char * permitted_paths)
4416{
4417	if (!name || !permitted_paths) {
4418		LD_LOGE("dlns_set_namespace_permitted_paths name or permitted_paths is null.");
4419		return EINVAL;
4420	}
4421
4422	pthread_rwlock_wrlock(&lock);
4423	const void *caller_addr = __builtin_return_address(0);
4424	if (is_permitted(caller_addr, name) == false) {
4425		pthread_rwlock_unlock(&lock);
4426		return EPERM;
4427	}
4428
4429	ns_t* ns = find_ns_by_name(name);
4430	if (!ns) {
4431		pthread_rwlock_unlock(&lock);
4432		LD_LOGE("dlns_set_namespace_permitted_paths fail, input ns name : [%{public}s] is not found.", name);
4433		return ENOKEY;
4434	}
4435
4436	ns_set_permitted_paths(ns, permitted_paths);
4437	pthread_rwlock_unlock(&lock);
4438	return 0;
4439}
4440
4441int dlns_set_namespace_allowed_libs(const char * name, const char * allowed_libs)
4442{
4443	if (!name || !allowed_libs) {
4444		LD_LOGE("dlns_set_namespace_allowed_libs name or allowed_libs is null.");
4445		return EINVAL;
4446	}
4447
4448	pthread_rwlock_wrlock(&lock);
4449	const void *caller_addr = __builtin_return_address(0);
4450	if (is_permitted(caller_addr, name) == false) {
4451		pthread_rwlock_unlock(&lock);
4452		return EPERM;
4453	}
4454
4455	ns_t* ns = find_ns_by_name(name);
4456	if (!ns) {
4457		pthread_rwlock_unlock(&lock);
4458		LD_LOGE("dlns_set_namespace_allowed_libs fail, input ns name : [%{public}s] is not found.", name);
4459		return ENOKEY;
4460	}
4461
4462	ns_set_allowed_libs(ns, allowed_libs);
4463	pthread_rwlock_unlock(&lock);
4464	return 0;
4465}
4466
4467int handle_asan_path_open(int fd, const char *name, ns_t *namespace, char *buf, size_t buf_size)
4468{
4469	LD_LOGD("handle_asan_path_open fd:%{public}d, name:%{public}s , namespace:%{public}s .",
4470		fd,
4471		name,
4472		namespace ? namespace->ns_name : "NULL");
4473	int fd_tmp = fd;
4474	if (fd == -1 && (namespace->asan_lib_paths || namespace->lib_paths)) {
4475		if (namespace->lib_paths && namespace->asan_lib_paths) {
4476			size_t newlen = strlen(namespace->asan_lib_paths) + strlen(namespace->lib_paths) + 2;
4477			char *new_lib_paths = malloc(newlen);
4478			memset(new_lib_paths, 0, newlen);
4479			strcpy(new_lib_paths, namespace->asan_lib_paths);
4480			strcat(new_lib_paths, ":");
4481			strcat(new_lib_paths, namespace->lib_paths);
4482			fd_tmp = path_open(name, new_lib_paths, buf, buf_size);
4483			LD_LOGD("handle_asan_path_open path_open new_lib_paths:%{public}s ,fd: %{public}d.", new_lib_paths, fd_tmp);
4484			free(new_lib_paths);
4485		} else if (namespace->asan_lib_paths) {
4486			fd_tmp = path_open(name, namespace->asan_lib_paths, buf, buf_size);
4487			LD_LOGD("handle_asan_path_open path_open asan_lib_paths:%{public}s ,fd: %{public}d.",
4488				namespace->asan_lib_paths,
4489				fd_tmp);
4490		} else {
4491			fd_tmp = path_open(name, namespace->lib_paths, buf, buf_size);
4492			LD_LOGD(
4493				"handle_asan_path_open path_open lib_paths:%{public}s ,fd: %{public}d.", namespace->lib_paths, fd_tmp);
4494		}
4495	}
4496	return fd_tmp;
4497}
4498
4499void* dlopen_ext(const char *file, int mode, const dl_extinfo *extinfo)
4500{
4501	const void *caller_addr = __builtin_return_address(0);
4502	musl_log_reset();
4503	ld_log_reset();
4504	if (extinfo != NULL) {
4505		if ((extinfo->flag & ~(DL_EXT_VALID_FLAG_BITS)) != 0) {
4506			LD_LOGE("Error dlopen_ext %{public}s: invalid flag %{public}x", file, extinfo->flag);
4507			return NULL;
4508		}
4509	}
4510	LD_LOGI("dlopen_ext file:%{public}s, mode:%{public}x , caller_addr:%{public}p , extinfo->flag:%{public}x",
4511		file,
4512		mode,
4513		caller_addr,
4514		extinfo ? extinfo->flag : 0);
4515	return dlopen_impl(file, mode, NULL, caller_addr, extinfo);
4516}
4517
4518#ifdef LOAD_ORDER_RANDOMIZATION
4519static void open_library_by_path(const char *name, const char *s, struct loadtask *task, struct zip_info *z_info)
4520{
4521	char *buf = task->buf;
4522	size_t buf_size = sizeof task->buf;
4523	size_t l;
4524	for (;;) {
4525		s += strspn(s, ":\n");
4526		l = strcspn(s, ":\n");
4527		if (l-1 >= INT_MAX) return;
4528		if (snprintf(buf, buf_size, "%.*s/%s", (int)l, s, name) < buf_size) {
4529			char *separator = strstr(buf, ZIP_FILE_PATH_SEPARATOR);
4530			if (separator != NULL) {
4531				int res = open_uncompressed_library_in_zipfile(buf, z_info, separator);
4532				if (res == 0) {
4533					task->fd = z_info->fd;
4534					task->file_offset = z_info->file_offset;
4535					break;
4536				} else {
4537					memset(z_info->path_buf, 0, sizeof(z_info->path_buf));
4538				}
4539			} else {
4540				if ((task->fd = open(buf, O_RDONLY|O_CLOEXEC))>=0) break;
4541			}
4542		}
4543		s += l;
4544	}
4545	return;
4546}
4547
4548static void handle_asan_path_open_by_task(int fd, const char *name, ns_t *namespace, struct loadtask *task,
4549										  struct zip_info *z_info)
4550{
4551	LD_LOGD("handle_asan_path_open_by_task fd:%{public}d, name:%{public}s , namespace:%{public}s .",
4552			fd,
4553			name,
4554			namespace ? namespace->ns_name : "NULL");
4555	if (fd == -1 && (namespace->asan_lib_paths || namespace->lib_paths)) {
4556		if (namespace->lib_paths && namespace->asan_lib_paths) {
4557			size_t newlen = strlen(namespace->asan_lib_paths) + strlen(namespace->lib_paths) + 2;
4558			char *new_lib_paths = malloc(newlen);
4559			memset(new_lib_paths, 0, newlen);
4560			strcpy(new_lib_paths, namespace->asan_lib_paths);
4561			strcat(new_lib_paths, ":");
4562			strcat(new_lib_paths, namespace->lib_paths);
4563			open_library_by_path(name, new_lib_paths, task, z_info);
4564			LD_LOGD("handle_asan_path_open_by_task open_library_by_path new_lib_paths:%{public}s ,fd: %{public}d.",
4565					new_lib_paths,
4566					task->fd);
4567			free(new_lib_paths);
4568		} else if (namespace->asan_lib_paths) {
4569			open_library_by_path(name, namespace->asan_lib_paths, task, z_info);
4570			LD_LOGD("handle_asan_path_open_by_task open_library_by_path asan_lib_paths:%{public}s ,fd: %{public}d.",
4571					namespace->asan_lib_paths,
4572					task->fd);
4573		} else {
4574			open_library_by_path(name, namespace->lib_paths, task, z_info);
4575			LD_LOGD("handle_asan_path_open_by_task open_library_by_path lib_paths:%{public}s ,fd: %{public}d.",
4576					namespace->lib_paths,
4577					task->fd);
4578		}
4579	}
4580	return;
4581}
4582
4583/* Used to get an uncompress library offset in zip file, then we can use the offset to mmap the library directly. */
4584int open_uncompressed_library_in_zipfile(const char *path, struct zip_info *z_info, char *separator)
4585{
4586	struct local_file_header zip_file_header;
4587	struct central_dir_entry c_dir_entry;
4588	struct zip_end_locator end_locator;
4589
4590	/* Use "'!/' to split the path into zipfile path and library path in zipfile.
4591	 * For example:
4592	 * - path: x/xx/xxx.zip!/x/xx/xxx.so
4593	 * - zipfile path: x/xx/xxx.zip
4594	 * - library path in zipfile: x/xx/xxx.so  */
4595	if (strlcpy(z_info->path_buf, path, PATH_BUF_SIZE) >= PATH_BUF_SIZE) {
4596		LD_LOGE("Open uncompressed library: input path %{public}s is too long.", path);
4597		return -1;
4598	}
4599	z_info->path_buf[separator - path] = '\0';
4600	z_info->file_path_index = separator - path + 2;
4601	char *zip_file_path = z_info->path_buf;
4602	char *lib_path = &z_info->path_buf[z_info->file_path_index];
4603	if (zip_file_path == NULL || lib_path == NULL) {
4604		LD_LOGE("Open uncompressed library: get zip and lib path failed.");
4605		return -1;
4606	}
4607	LD_LOGD("Open uncompressed library: input path: %{public}s, zip file path: %{public}s, library path: %{public}s.",
4608			path, zip_file_path, lib_path);
4609
4610	// Get zip file length
4611	FILE *zip_file = fopen(zip_file_path, "re");
4612	if (zip_file == NULL) {
4613		LD_LOGE("Open uncompressed library: fopen %{public}s failed.", zip_file_path);
4614		return -1;
4615	}
4616	if (fseek(zip_file, 0, SEEK_END) != 0) {
4617		LD_LOGE("Open uncompressed library: fseek SEEK_END failed.");
4618		fclose(zip_file);
4619		return -1;
4620	}
4621	int64_t zip_file_len = ftell(zip_file);
4622	if (zip_file_len == -1) {
4623		LD_LOGE("Open uncompressed library: get zip file length failed.");
4624		fclose(zip_file);
4625		return -1;
4626	}
4627
4628	// Read end of central directory record.
4629	size_t end_locator_len = sizeof(end_locator);
4630	size_t end_locator_pos = zip_file_len - end_locator_len;
4631	if (fseek(zip_file, end_locator_pos, SEEK_SET) != 0) {
4632		LD_LOGE("Open uncompressed library: fseek end locator position failed.");
4633		fclose(zip_file);
4634		return -1;
4635	}
4636	if (fread(&end_locator, sizeof(end_locator), 1, zip_file) != 1 || end_locator.signature != EOCD_SIGNATURE) {
4637		LD_LOGE("Open uncompressed library: fread end locator failed.");
4638		fclose(zip_file);
4639		return -1;
4640	}
4641
4642	char file_name[PATH_BUF_SIZE];
4643	uint64_t current_dir_pos = end_locator.offset;
4644	for (uint16_t i = 0; i < end_locator.total_entries; i++) {
4645		// Read central dir entry.
4646		if (fseek(zip_file, current_dir_pos, SEEK_SET) != 0) {
4647			LD_LOGE("Open uncompressed library: fseek current centra dir entry position failed.");
4648			fclose(zip_file);
4649			return -1;
4650		}
4651		if (fread(&c_dir_entry, sizeof(c_dir_entry), 1, zip_file) != 1 || c_dir_entry.signature != CENTRAL_SIGNATURE) {
4652			LD_LOGE("Open uncompressed library: fread centra dir entry failed.");
4653			fclose(zip_file);
4654			return -1;
4655		}
4656
4657		if (fread(file_name, c_dir_entry.name_size, 1, zip_file) != 1) {
4658			LD_LOGE("Open uncompressed library: fread file name failed.");
4659			fclose(zip_file);
4660			return -1;
4661		}
4662		if (strcmp(file_name, lib_path) == 0) {
4663			// Read local file header.
4664			if (fseek(zip_file, c_dir_entry.local_header_offset, SEEK_SET) != 0) {
4665				LD_LOGE("Open uncompressed library: fseek local file header failed.");
4666				fclose(zip_file);
4667				return -1;
4668			}
4669			if (fread(&zip_file_header, sizeof(zip_file_header), 1, zip_file) != 1) {
4670				LD_LOGE("Open uncompressed library: fread local file header failed.");
4671				fclose(zip_file);
4672				return -1;
4673			}
4674			if (zip_file_header.signature != LOCAL_FILE_HEADER_SIGNATURE) {
4675				LD_LOGE("Open uncompressed library: read local file header signature error.");
4676				fclose(zip_file);
4677				return -1;
4678			}
4679
4680			z_info->file_offset = c_dir_entry.local_header_offset + sizeof(zip_file_header) +
4681									zip_file_header.name_size + zip_file_header.extra_size;
4682			if (zip_file_header.compression_method != COMPRESS_STORED || z_info->file_offset % PAGE_SIZE != 0) {
4683				LD_LOGE("Open uncompressed library: open %{public}s in %{public}s failed because of misalignment or saved with compression."
4684						"compress method %{public}d, file offset %{public}lu",
4685						lib_path, zip_file_path, zip_file_header.compression_method, z_info->file_offset);
4686				fclose(zip_file);
4687				return -2;
4688			}
4689			z_info->found = true;
4690			break;
4691		}
4692
4693		memset(file_name, 0, sizeof(file_name));
4694		current_dir_pos += sizeof(c_dir_entry);
4695		current_dir_pos += c_dir_entry.name_size + c_dir_entry.extra_size + c_dir_entry.comment_size;
4696	}
4697	if(!z_info->found) {
4698		LD_LOGE("Open uncompressed library: %{public}s was not found in %{public}s.", lib_path, zip_file_path);
4699		fclose(zip_file);
4700		return -3;
4701	}
4702	z_info->fd = fileno(zip_file);
4703
4704	return 0;
4705}
4706
4707static bool map_library_header(struct loadtask *task)
4708{
4709	off_t off_start;
4710	Phdr *ph;
4711	size_t i;
4712	size_t str_size;
4713	off_t str_table;
4714
4715	ssize_t l = pread(task->fd, task->ehdr_buf, sizeof task->ehdr_buf, task->file_offset);
4716	task->eh = task->ehdr_buf;
4717	if (l < 0) {
4718		LD_LOGE("Error mapping header %{public}s: failed to read fd errno: %{public}d", task->name, errno);
4719		return false;
4720	}
4721	if (l < sizeof(Ehdr) || (task->eh->e_type != ET_DYN && task->eh->e_type != ET_EXEC)) {
4722		LD_LOGE("Error mapping header %{public}s: invaliled Ehdr l=%{public}d", task->name, l);
4723		goto noexec;
4724	}
4725	task->phsize = task->eh->e_phentsize * task->eh->e_phnum;
4726	if (task->phsize > sizeof task->ehdr_buf - sizeof(Ehdr)) {
4727		task->allocated_buf = malloc(task->phsize);
4728		if (!task->allocated_buf) {
4729			LD_LOGE("Error mapping header %{public}s: failed to alloc memory errno: %{public}d", task->name, errno);
4730			return false;
4731		}
4732		l = pread(task->fd, task->allocated_buf, task->phsize, task->eh->e_phoff + task->file_offset);
4733		if (l < 0) {
4734			LD_LOGE("Error mapping header %{public}s: failed to pread errno: %{public}d", task->name, errno);
4735			goto error;
4736		}
4737		if (l != task->phsize) {
4738			LD_LOGE("Error mapping header %{public}s: unmatched phsize errno: %{public}d", task->name, errno);
4739			goto noexec;
4740		}
4741		ph = task->ph0 = task->allocated_buf;
4742	} else if (task->eh->e_phoff + task->phsize > l) {
4743		l = pread(task->fd, task->ehdr_buf + 1, task->phsize, task->eh->e_phoff + task->file_offset);
4744		if (l < 0) {
4745			LD_LOGE("Error mapping header %{public}s: failed to pread errno: %{public}d", task->name, errno);
4746			goto error;
4747		}
4748		if (l != task->phsize) {
4749			LD_LOGE("Error mapping header %{public}s: unmatched phsize", task->name);
4750			goto noexec;
4751		}
4752		ph = task->ph0 = (void *)(task->ehdr_buf + 1);
4753	} else {
4754		ph = task->ph0 = (void *)((char *)task->ehdr_buf + task->eh->e_phoff);
4755	}
4756
4757	for (i = task->eh->e_phnum; i; i--, ph = (void *)((char *)ph + task->eh->e_phentsize)) {
4758		if (ph->p_type == PT_DYNAMIC) {
4759			task->dyn = ph->p_vaddr;
4760		} else if (ph->p_type == PT_TLS) {
4761			task->tls_image = ph->p_vaddr;
4762			task->tls.align = ph->p_align;
4763			task->tls.len = ph->p_filesz;
4764			task->tls.size = ph->p_memsz;
4765		}
4766
4767		if (ph->p_type != PT_DYNAMIC) {
4768			continue;
4769		}
4770		// map the dynamic segment and the string table of the library
4771		off_start = ph->p_offset;
4772		off_start &= -PAGE_SIZE;
4773		task->dyn_map_len = ph->p_memsz + (ph->p_offset - off_start);
4774		/* The default value of file_offset is 0.
4775		 * The value of file_offset may be greater than 0 when opening library from zip file.
4776		 * The value of file_offset ensures PAGE_SIZE aligned. */
4777		task->dyn_map = mmap(0, task->dyn_map_len, PROT_READ, MAP_PRIVATE, task->fd, off_start + task->file_offset);
4778		if (task->dyn_map == MAP_FAILED) {
4779			LD_LOGE("Error mapping header %{public}s: failed to map dynamic section errno: %{public}d", task->name, errno);
4780			goto error;
4781		}
4782		task->dyn_addr = (size_t *)((unsigned char *)task->dyn_map + (ph->p_offset - off_start));
4783		size_t dyn_tmp;
4784		if (search_vec(task->dyn_addr, &dyn_tmp, DT_STRTAB)) {
4785			str_table = dyn_tmp;
4786		} else {
4787			LD_LOGE("Error mapping header %{public}s: DT_STRTAB not found", task->name);
4788			goto error;
4789		}
4790		if (search_vec(task->dyn_addr, &dyn_tmp, DT_STRSZ)) {
4791			str_size = dyn_tmp;
4792		} else {
4793			LD_LOGE("Error mapping header %{public}s: DT_STRSZ not found", task->name);
4794			goto error;
4795		}
4796	}
4797
4798	task->shsize = task->eh->e_shentsize * task->eh->e_shnum;
4799	off_start = task->eh->e_shoff;
4800	off_start &= -PAGE_SIZE;
4801	task->shsize += task->eh->e_shoff - off_start;
4802	task->shdr_allocated_buf = mmap(0, task->shsize, PROT_READ, MAP_PRIVATE, task->fd, off_start + task->file_offset);
4803	if (task->shdr_allocated_buf == MAP_FAILED) {
4804		LD_LOGE("Error mapping section header %{public}s: failed to map shdr_allocated_buf errno: %{public}d",
4805			task->name, errno);
4806		goto error;
4807	}
4808	Shdr *sh = (char *)task->shdr_allocated_buf + task->eh->e_shoff - off_start;
4809	for (i = task->eh->e_shnum; i; i--, sh = (void *)((char *)sh + task->eh->e_shentsize)) {
4810		if (sh->sh_type != SHT_STRTAB || sh->sh_addr != str_table || sh->sh_size != str_size) {
4811			continue;
4812		}
4813		off_start = sh->sh_offset;
4814		off_start &= -PAGE_SIZE;
4815		task->str_map_len = sh->sh_size + (sh->sh_offset - off_start);
4816		task->str_map = mmap(0, task->str_map_len, PROT_READ, MAP_PRIVATE, task->fd, off_start + task->file_offset);
4817		if (task->str_map == MAP_FAILED) {
4818			LD_LOGE("Error mapping section header %{public}s: failed to map string section errno: %{public}d",
4819				task->name, errno);
4820			goto error;
4821		}
4822		task->str_addr = (char *)task->str_map + sh->sh_offset - off_start;
4823		break;
4824	}
4825	if (!task->dyn) {
4826		LD_LOGE("Error mapping header %{public}s: dynamic section not found", task->name);
4827		goto noexec;
4828	}
4829	return true;
4830noexec:
4831	errno = ENOEXEC;
4832error:
4833	free(task->allocated_buf);
4834	task->allocated_buf = NULL;
4835	if (task->shdr_allocated_buf != MAP_FAILED) {
4836		munmap(task->shdr_allocated_buf, task->shsize);
4837		task->shdr_allocated_buf = MAP_FAILED;
4838	}
4839	return false;
4840}
4841
4842static bool task_map_library(struct loadtask *task, struct reserved_address_params *reserved_params)
4843{
4844	size_t addr_min = SIZE_MAX, addr_max = 0, map_len;
4845	size_t this_min, this_max;
4846	size_t nsegs = 0;
4847	off_t off_start;
4848	Phdr *ph = task->ph0;
4849	unsigned prot;
4850	unsigned char *map = MAP_FAILED, *base;
4851	size_t i;
4852	int map_flags = MAP_PRIVATE;
4853	size_t start_addr;
4854	size_t start_alignment = PAGE_SIZE;
4855	bool hugepage_enabled = false;
4856
4857	for (i = task->eh->e_phnum; i; i--, ph = (void *)((char *)ph + task->eh->e_phentsize)) {
4858		if (ph->p_type == PT_GNU_RELRO) {
4859			task->p->relro_start = ph->p_vaddr & -PAGE_SIZE;
4860			task->p->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE;
4861		} else if (ph->p_type == PT_GNU_STACK) {
4862			if (!runtime && ph->p_memsz > __default_stacksize) {
4863				__default_stacksize =
4864					ph->p_memsz < DEFAULT_STACK_MAX ?
4865					ph->p_memsz : DEFAULT_STACK_MAX;
4866			}
4867		}
4868		if (ph->p_type != PT_LOAD) {
4869			continue;
4870		}
4871		nsegs++;
4872		if (ph->p_vaddr < addr_min) {
4873			addr_min = ph->p_vaddr;
4874			off_start = ph->p_offset;
4875			prot = (((ph->p_flags & PF_R) ? PROT_READ : 0) |
4876				((ph->p_flags & PF_W) ? PROT_WRITE : 0) |
4877				((ph->p_flags & PF_X) ? PROT_EXEC : 0));
4878		}
4879		if (ph->p_vaddr + ph->p_memsz > addr_max) {
4880			addr_max = ph->p_vaddr + ph->p_memsz;
4881		}
4882	}
4883	if (!task->dyn) {
4884		LD_LOGE("Error mapping library: !task->dyn dynamic section not found task->name=%{public}s", task->name);
4885		goto noexec;
4886	}
4887	if (DL_FDPIC && !(task->eh->e_flags & FDPIC_CONSTDISP_FLAG)) {
4888		task->p->loadmap = calloc(1, sizeof(struct fdpic_loadmap) + nsegs * sizeof(struct fdpic_loadseg));
4889		if (!task->p->loadmap) {
4890			LD_LOGE("Error mapping library: calloc failed errno=%{public}d nsegs=%{public}d", errno, nsegs);
4891			goto error;
4892		}
4893		task->p->loadmap->nsegs = nsegs;
4894		for (ph = task->ph0, i = 0; i < nsegs; ph = (void *)((char *)ph + task->eh->e_phentsize)) {
4895			if (ph->p_type != PT_LOAD) {
4896				continue;
4897			}
4898			prot = (((ph->p_flags & PF_R) ? PROT_READ : 0) |
4899				((ph->p_flags & PF_W) ? PROT_WRITE : 0) |
4900				((ph->p_flags & PF_X) ? PROT_EXEC : 0));
4901			map = mmap(0, ph->p_memsz + (ph->p_vaddr & PAGE_SIZE - 1),
4902				prot, MAP_PRIVATE,
4903				task->fd, ph->p_offset & -PAGE_SIZE + task->file_offset);
4904			if (map == MAP_FAILED) {
4905				unmap_library(task->p);
4906				LD_LOGE("Error mapping library: PT_LOAD mmap failed task->name=%{public}s errno=%{public}d map_len=%{public}d",
4907					task->name, errno, ph->p_memsz + (ph->p_vaddr & PAGE_SIZE - 1));
4908				goto error;
4909			}
4910			task->p->loadmap->segs[i].addr = (size_t)map +
4911				(ph->p_vaddr & PAGE_SIZE - 1);
4912			task->p->loadmap->segs[i].p_vaddr = ph->p_vaddr;
4913			task->p->loadmap->segs[i].p_memsz = ph->p_memsz;
4914			i++;
4915			if (prot & PROT_WRITE) {
4916				size_t brk = (ph->p_vaddr & PAGE_SIZE - 1) + ph->p_filesz;
4917				size_t pgbrk = (brk + PAGE_SIZE - 1) & -PAGE_SIZE;
4918				size_t pgend = (brk + ph->p_memsz - ph->p_filesz + PAGE_SIZE - 1) & -PAGE_SIZE;
4919				if (pgend > pgbrk && mmap_fixed(map + pgbrk,
4920					pgend - pgbrk, prot,
4921					MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS,
4922					-1, off_start) == MAP_FAILED)
4923					LD_LOGE("Error mapping library: PROT_WRITE mmap_fixed failed errno=%{public}d", errno);
4924					goto error;
4925				memset(map + brk, 0, pgbrk - brk);
4926			}
4927		}
4928		map = (void *)task->p->loadmap->segs[0].addr;
4929		map_len = 0;
4930		goto done_mapping;
4931	}
4932	addr_max += PAGE_SIZE - 1;
4933	addr_max &= -PAGE_SIZE;
4934	addr_min &= -PAGE_SIZE;
4935	off_start &= -PAGE_SIZE;
4936	map_len = addr_max - addr_min + off_start;
4937	start_addr = addr_min;
4938
4939	hugepage_enabled = get_transparent_hugepages_supported();
4940	if (hugepage_enabled) {
4941		size_t maxinum_alignment = phdr_table_get_maxinum_alignment(task->ph0, task->eh->e_phnum);
4942
4943		start_alignment = maxinum_alignment == KPMD_SIZE ? KPMD_SIZE : PAGE_SIZE;
4944	}
4945
4946	if (reserved_params) {
4947		if (map_len > reserved_params->reserved_size) {
4948			if (reserved_params->must_use_reserved) {
4949				LD_LOGE("Error mapping library: map len is larger than reserved address task->name=%{public}s", task->name);
4950				goto error;
4951			}
4952		} else {
4953			start_addr = ((size_t)reserved_params->start_addr - 1 + PAGE_SIZE) & -PAGE_SIZE;
4954			map_flags |= MAP_FIXED;
4955		}
4956	}
4957
4958	/* we will find a mapping_align aligned address as the start of dso
4959	 * so we need a tmp_map_len as map_len + mapping_align to make sure
4960	 * we have enough space to shift the dso to the correct location. */
4961	size_t mapping_align = start_alignment > LIBRARY_ALIGNMENT ? start_alignment : LIBRARY_ALIGNMENT;
4962	size_t tmp_map_len = ALIGN(map_len, mapping_align) + mapping_align - PAGE_SIZE;
4963
4964	/* map the whole load segments with PROT_READ first for security consideration. */
4965	prot = PROT_READ;
4966
4967	/* if reserved_params exists, we should use start_addr as prefered result to do the mmap operation */
4968	if (reserved_params) {
4969		map = DL_NOMMU_SUPPORT
4970			? mmap((void *)start_addr, map_len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)
4971			: mmap((void *)start_addr, map_len, prot, map_flags, task->fd, off_start + task->file_offset);
4972		if (map == MAP_FAILED) {
4973			LD_LOGE("Error mapping library: reserved_params mmap failed errno=%{public}d DL_NOMMU_SUPPORT=%{public}d"
4974				" task->fd=%{public}d task->name=%{public}s map_len=%{public}d",
4975				errno, DL_NOMMU_SUPPORT, task->fd, task->name, map_len);
4976			goto error;
4977		}
4978		if (reserved_params && map_len < reserved_params->reserved_size) {
4979			reserved_params->reserved_size -= (map_len + (start_addr - (size_t)reserved_params->start_addr));
4980			reserved_params->start_addr = (void *)((uint8_t *)map + map_len);
4981		}
4982	/* if reserved_params does not exist, we should use real_map as prefered result to do the mmap operation */
4983	} else {
4984		/* use tmp_map_len to mmap enough space for the dso with anonymous mapping */
4985		unsigned char *temp_map = mmap((void *)NULL, tmp_map_len, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
4986		if (temp_map == MAP_FAILED) {
4987			LD_LOGE("Error mapping library: !reserved_params mmap failed errno=%{public}d tmp_map_len=%{public}d",
4988				errno, tmp_map_len);
4989			goto error;
4990		}
4991
4992		/* find the mapping_align aligned address */
4993		unsigned char *real_map = (unsigned char*)ALIGN((uintptr_t)temp_map, mapping_align);
4994
4995		/* mummap the space we mmap before so that we can mmap correct space again */
4996		munmap(temp_map, tmp_map_len);
4997
4998		map = DL_NOMMU_SUPPORT
4999			? mmap(real_map, map_len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)
5000			/* use map_len to mmap correct space for the dso with file mapping */
5001			: mmap(real_map, map_len, prot, map_flags, task->fd, off_start + task->file_offset);
5002		if (map == MAP_FAILED) {
5003			LD_LOGE("Error mapping library: !reserved_params mmap failed errno=%{public}d DL_NOMMU_SUPPORT=%{public}d"
5004				"task->fd=%{public}d task->name=%{public}s map_len=%{public}d",
5005				errno, DL_NOMMU_SUPPORT, task->fd, task->name, map_len);
5006			goto error;
5007		}
5008	}
5009	task->p->map = map;
5010	task->p->map_len = map_len;
5011	/* If the loaded file is not relocatable and the requested address is
5012	 * not available, then the load operation must fail. */
5013	if (task->eh->e_type != ET_DYN && addr_min && map != (void *)addr_min) {
5014		LD_LOGE("Error mapping library: ET_DYN task->name=%{public}s", task->name);
5015		errno = EBUSY;
5016		goto error;
5017	}
5018	base = map - addr_min;
5019	task->p->phdr = 0;
5020	task->p->phnum = 0;
5021	for (ph = task->ph0, i = task->eh->e_phnum; i; i--, ph = (void *)((char *)ph + task->eh->e_phentsize)) {
5022		if (ph->p_type == PT_OHOS_RANDOMDATA) {
5023			fill_random_data((void *)(ph->p_vaddr + base), ph->p_memsz);
5024			continue;
5025		}
5026		if (ph->p_type != PT_LOAD) {
5027			continue;
5028		}
5029		/* Check if the programs headers are in this load segment, and
5030		 * if so, record the address for use by dl_iterate_phdr. */
5031		if (!task->p->phdr && task->eh->e_phoff >= ph->p_offset
5032			&& task->eh->e_phoff + task->phsize <= ph->p_offset + ph->p_filesz) {
5033			task->p->phdr = (void *)(base + ph->p_vaddr + (task->eh->e_phoff - ph->p_offset));
5034			task->p->phnum = task->eh->e_phnum;
5035			task->p->phentsize = task->eh->e_phentsize;
5036		}
5037		this_min = ph->p_vaddr & -PAGE_SIZE;
5038		this_max = ph->p_vaddr + ph->p_memsz + PAGE_SIZE - 1 & -PAGE_SIZE;
5039		off_start = ph->p_offset & -PAGE_SIZE;
5040		prot = (((ph->p_flags & PF_R) ? PROT_READ : 0) |
5041			((ph->p_flags & PF_W) ? PROT_WRITE : 0) |
5042			((ph->p_flags & PF_X) ? PROT_EXEC : 0));
5043		/* Reuse the existing mapping for the lowest-address LOAD */
5044		if (mmap_fixed(
5045				base + this_min,
5046				this_max - this_min,
5047				prot, MAP_PRIVATE | MAP_FIXED,
5048				task->fd,
5049				off_start + task->file_offset) == MAP_FAILED) {
5050			LD_LOGE("Error mapping library: mmap fix failed task->name=%{public}s errno=%{public}d", task->name, errno);
5051			goto error;
5052		}
5053		if ((ph->p_flags & PF_X) && (ph->p_align == KPMD_SIZE) && hugepage_enabled)
5054			madvise(base + this_min, this_max - this_min, MADV_HUGEPAGE);
5055		if (ph->p_memsz > ph->p_filesz && (ph->p_flags & PF_W)) {
5056			size_t brk = (size_t)base + ph->p_vaddr + ph->p_filesz;
5057			size_t pgbrk = brk + PAGE_SIZE - 1 & -PAGE_SIZE;
5058			size_t zeromap_size = (size_t)base + this_max - pgbrk;
5059			memset((void *)brk, 0, pgbrk - brk & PAGE_SIZE - 1);
5060			if (pgbrk - (size_t)base < this_max && mmap_fixed(
5061				(void *)pgbrk,
5062				zeromap_size,
5063				prot,
5064				MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS,
5065				-1,
5066				0) == MAP_FAILED) {
5067				LD_LOGE("Error mapping library: PF_W mmap fix failed errno=%{public}d task->name=%{public}s zeromap_size=%{public}d",
5068					errno, task->name, zeromap_size);
5069				goto error;
5070			}
5071			set_bss_vma_name(task->p->name, (void *)pgbrk, zeromap_size);
5072		}
5073	}
5074	for (i = 0; ((size_t *)(base + task->dyn))[i]; i += NEXT_DYNAMIC_INDEX) {
5075		if (((size_t *)(base + task->dyn))[i] == DT_TEXTREL) {
5076			if (mprotect(map, map_len, PROT_READ | PROT_WRITE | PROT_EXEC) && errno != ENOSYS) {
5077				LD_LOGE("Error mapping library: mprotect failed task->name=%{public}s errno=%{public}d", task->name, errno);
5078				goto error;
5079			}
5080			break;
5081		}
5082	}
5083done_mapping:
5084	task->p->base = base;
5085	task->p->dynv = laddr(task->p, task->dyn);
5086	if (task->p->tls.size) {
5087		task->p->tls.image = laddr(task->p, task->tls_image);
5088	}
5089	free(task->allocated_buf);
5090	task->allocated_buf = NULL;
5091	if (task->shdr_allocated_buf != MAP_FAILED) {
5092		munmap(task->shdr_allocated_buf, task->shsize);
5093		task->shdr_allocated_buf = MAP_FAILED;
5094	}
5095	return true;
5096noexec:
5097	errno = ENOEXEC;
5098error:
5099	if (map != MAP_FAILED) {
5100		unmap_library(task->p);
5101	}
5102	free(task->allocated_buf);
5103	task->allocated_buf = NULL;
5104	if (task->shdr_allocated_buf != MAP_FAILED) {
5105		munmap(task->shdr_allocated_buf, task->shsize);
5106		task->shdr_allocated_buf = MAP_FAILED;
5107	}
5108	return false;
5109}
5110
5111static bool resolve_fd_to_realpath(struct loadtask *task)
5112{
5113	char proc_self_fd[32];
5114	static char resolved_path[PATH_MAX];
5115
5116	int ret = snprintf(proc_self_fd, sizeof(proc_self_fd), "/proc/self/fd/%d", task->fd);
5117	if (ret < 0 || ret >= sizeof(proc_self_fd)) {
5118		return false;
5119	}
5120	ssize_t len = readlink(proc_self_fd, resolved_path, sizeof(resolved_path) - 1);
5121	if (len < 0) {
5122		return false;
5123	}
5124	resolved_path[len] = '\0';
5125	strncpy(task->buf, resolved_path, PATH_MAX);
5126
5127	return true;
5128}
5129
5130static bool load_library_header(struct loadtask *task)
5131{
5132	const char *name = task->name;
5133	struct dso *needed_by = task->needed_by;
5134	ns_t *namespace = task->namespace;
5135	bool check_inherited = task->check_inherited;
5136	struct zip_info z_info;
5137
5138	bool map = false;
5139	struct stat st;
5140	size_t alloc_size;
5141	int n_th = 0;
5142	int is_self = 0;
5143
5144	if (!*name) {
5145		errno = EINVAL;
5146		return false;
5147	}
5148
5149	/* Catch and block attempts to reload the implementation itself */
5150	if (name[NAME_INDEX_ZERO] == 'l' && name[NAME_INDEX_ONE] == 'i' && name[NAME_INDEX_TWO] == 'b') {
5151		static const char reserved[] =
5152			"c.pthread.rt.m.dl.util.xnet.";
5153		const char *rp, *next;
5154		for (rp = reserved; *rp; rp = next) {
5155			next = strchr(rp, '.') + 1;
5156			if (strncmp(name + NAME_INDEX_THREE, rp, next - rp) == 0) {
5157				break;
5158			}
5159		}
5160		if (*rp) {
5161			if (ldd_mode) {
5162				/* Track which names have been resolved
5163				 * and only report each one once. */
5164				static unsigned reported;
5165				unsigned mask = 1U << (rp - reserved);
5166				if (!(reported & mask)) {
5167					reported |= mask;
5168					dprintf(1, "\t%s => %s (%p)\n",
5169						name, ldso.name,
5170						ldso.base);
5171				}
5172			}
5173			is_self = 1;
5174		}
5175	}
5176	if (!strcmp(name, ldso.name)) {
5177		is_self = 1;
5178	}
5179	if (is_self) {
5180		if (!ldso.prev) {
5181			tail->next = &ldso;
5182			ldso.prev = tail;
5183			tail = &ldso;
5184			ldso.namespace = namespace;
5185			ns_add_dso(namespace, &ldso);
5186		}
5187		task->isloaded = true;
5188		task->p = &ldso;
5189		return true;
5190	}
5191	if (strchr(name, '/')) {
5192		char *separator = strstr(name, ZIP_FILE_PATH_SEPARATOR);
5193		if (separator != NULL) {
5194			int res = open_uncompressed_library_in_zipfile(name, &z_info, separator);
5195			if (!res) {
5196				task->pathname = name;
5197				if (!is_accessible(namespace, task->pathname, g_is_asan, check_inherited)) {
5198					LD_LOGE("Open uncompressed library: check ns accessible failed, pathname %{public}s namespace %{public}s.",
5199							task->pathname, namespace ? namespace->ns_name : "NULL");
5200					task->fd = -1;
5201				} else {
5202					task->fd = z_info.fd;
5203					task->file_offset = z_info.file_offset;
5204				}
5205			} else {
5206				LD_LOGE("Open uncompressed library in zip file failed, name:%{public}s res:%{public}d", name, res);
5207				return false;
5208			}
5209		} else {
5210			task->pathname = name;
5211			if (!is_accessible(namespace, task->pathname, g_is_asan, check_inherited)) {
5212				LD_LOGE("Open absolute_path library: check ns accessible failed, pathname %{public}s namespace %{public}s.",
5213						task->pathname, namespace ? namespace->ns_name : "NULL");
5214				task->fd = -1;
5215			} else {
5216				task->fd = open(name, O_RDONLY | O_CLOEXEC);
5217			}
5218		}
5219	} else {
5220		/* Search for the name to see if it's already loaded */
5221		/* Search in namespace */
5222		task->p = find_library_by_name(name, namespace, check_inherited);
5223		if (task->p) {
5224			task->isloaded = true;
5225			LD_LOGD("find_library_by_name(name=%{public}s ns=%{public}s) already loaded by %{public}s in %{public}s namespace  ",
5226					name, namespace->ns_name, task->p->name, task->p->namespace->ns_name);
5227			return true;
5228		}
5229		if (strlen(name) > NAME_MAX) {
5230			LD_LOGE("load_library name length is larger than NAME_MAX:%{public}s.", name);
5231			return false;
5232		}
5233		task->fd = -1;
5234		if (namespace->env_paths) {
5235			open_library_by_path(name, namespace->env_paths, task, &z_info);
5236		}
5237		for (task->p = needed_by; task->fd == -1 && task->p; task->p = task->p->needed_by) {
5238			if (fixup_rpath(task->p, task->buf, sizeof task->buf) < 0) {
5239				task->fd = INVALID_FD_INHIBIT_FURTHER_SEARCH; /* Inhibit further search. */
5240			}
5241			if (task->p->rpath) {
5242				open_library_by_path(name, task->p->rpath, task, &z_info);
5243				if (task->fd != -1 && resolve_fd_to_realpath(task)) {
5244					if (!is_accessible(namespace, task->buf, g_is_asan, check_inherited)) {
5245						LD_LOGE("Open library: check ns accessible failed, name %{public}s namespace %{public}s.",
5246								name, namespace ? namespace->ns_name : "NULL");
5247						close(task->fd);
5248						task->fd = -1;
5249					}
5250				}
5251			}
5252		}
5253		if (g_is_asan) {
5254			handle_asan_path_open_by_task(task->fd, name, namespace, task, &z_info);
5255			LD_LOGD("load_library handle_asan_path_open_by_task fd:%{public}d.", task->fd);
5256		} else {
5257			if (task->fd == -1 && namespace->lib_paths) {
5258				open_library_by_path(name, namespace->lib_paths, task, &z_info);
5259				LD_LOGD("load_library no asan lib_paths path_open fd:%{public}d.", task->fd);
5260			}
5261		}
5262		task->pathname = task->buf;
5263	}
5264	if (task->fd < 0) {
5265		if (!check_inherited || !namespace->ns_inherits) {
5266			LD_LOGE("Error loading header %{public}s, namespace %{public}s has no inherits, errno=%{public}d",
5267				task->name, namespace->ns_name, errno);
5268			return false;
5269		}
5270		/* Load lib in inherited namespace. Do not check inherited again.*/
5271		for (size_t i = 0; i < namespace->ns_inherits->num; i++) {
5272			ns_inherit *inherit = namespace->ns_inherits->inherits[i];
5273			if (strchr(name, '/') == 0 && !is_sharable(inherit, name)) {
5274				continue;
5275			}
5276			task->namespace = inherit->inherited_ns;
5277			task->check_inherited = false;
5278			if (load_library_header(task)) {
5279				return true;
5280			}
5281		}
5282		LD_LOGE("Error loading header: can't find library %{public}s in namespace: %{public}s",
5283			task->name, namespace->ns_name);
5284		return false;
5285	}
5286
5287	if (fstat(task->fd, &st) < 0) {
5288		LD_LOGE("Error loading header %{public}s: failed to get file state errno=%{public}d", task->name, errno);
5289		close(task->fd);
5290		task->fd = -1;
5291		return false;
5292	}
5293	/* Search in namespace */
5294	task->p = find_library_by_fstat(&st, namespace, check_inherited, task->file_offset);
5295	if (task->p) {
5296		/* If this library was previously loaded with a
5297		* pathname but a search found the same inode,
5298		* setup its shortname so it can be found by name. */
5299		if (!task->p->shortname && task->pathname != name) {
5300			task->p->shortname = strrchr(task->p->name, '/') + 1;
5301		}
5302		close(task->fd);
5303		task->fd = -1;
5304		task->isloaded = true;
5305		LD_LOGD("find_library_by_fstat(name=%{public}s ns=%{public}s) already loaded by %{public}s in %{public}s namespace  ",
5306				name, namespace->ns_name, task->p->name, task->p->namespace->ns_name);
5307		return true;
5308	}
5309
5310	map = noload ? 0 : map_library_header(task);
5311	if (!map) {
5312		LD_LOGE("Error loading header %{public}s: failed to map header", task->name);
5313		close(task->fd);
5314		task->fd = -1;
5315		return false;
5316	}
5317
5318	/* Allocate storage for the new DSO. When there is TLS, this
5319	 * storage must include a reservation for all pre-existing
5320	 * threads to obtain copies of both the new TLS, and an
5321	 * extended DTV capable of storing an additional slot for
5322	 * the newly-loaded DSO. */
5323	alloc_size = sizeof(struct dso) + strlen(task->pathname) + 1;
5324	if (runtime && task->tls.size) {
5325		size_t per_th = task->tls.size + task->tls.align + sizeof(void *) * (tls_cnt + TLS_CNT_INCREASE);
5326		n_th = libc.threads_minus_1 + 1;
5327		if (n_th > SSIZE_MAX / per_th) {
5328			alloc_size = SIZE_MAX;
5329		} else {
5330			alloc_size += n_th * per_th;
5331		}
5332	}
5333	task->p = calloc(1, alloc_size);
5334	if (!task->p) {
5335		LD_LOGE("Error loading header %{public}s: failed to allocate dso", task->name);
5336		close(task->fd);
5337		task->fd = -1;
5338		return false;
5339	}
5340	task->p->dev = st.st_dev;
5341	task->p->ino = st.st_ino;
5342	task->p->file_offset = task->file_offset;
5343	task->p->needed_by = needed_by;
5344	task->p->name = task->p->buf;
5345	strcpy(task->p->name, task->pathname);
5346	task->p->tls = task->tls;
5347	task->p->dynv = task->dyn_addr;
5348	task->p->strings = task->str_addr;
5349	size_t rpath_offset;
5350	size_t runpath_offset;
5351	if (search_vec(task->p->dynv, &rpath_offset, DT_RPATH))
5352		task->p->rpath_orig = task->p->strings + rpath_offset;
5353	if (search_vec(task->p->dynv, &runpath_offset, DT_RUNPATH))
5354		task->p->rpath_orig = task->p->strings + runpath_offset;
5355
5356	/* Add a shortname only if name arg was not an explicit pathname. */
5357	if (task->pathname != name) {
5358		task->p->shortname = strrchr(task->p->name, '/') + 1;
5359	}
5360
5361	if (task->p->tls.size) {
5362		task->p->tls_id = ++tls_cnt;
5363		task->p->new_dtv = (void *)(-sizeof(size_t) &
5364			(uintptr_t)(task->p->name + strlen(task->p->name) + sizeof(size_t)));
5365		task->p->new_tls = (void *)(task->p->new_dtv + n_th * (tls_cnt + 1));
5366	}
5367
5368	tail->next = task->p;
5369	task->p->prev = tail;
5370	tail = task->p;
5371
5372	/* Add dso to namespace */
5373	task->p->namespace = namespace;
5374	ns_add_dso(namespace, task->p);
5375	return true;
5376}
5377
5378static void task_load_library(struct loadtask *task, struct reserved_address_params *reserved_params)
5379{
5380	LD_LOGD("load_library loading ns=%{public}s name=%{public}s by_dlopen=%{public}d", task->namespace->ns_name, task->p->name, runtime);
5381	bool map = noload ? 0 : task_map_library(task, reserved_params);
5382	__close(task->fd);
5383	task->fd = -1;
5384	if (!map) {
5385		LD_LOGE("Error loading library %{public}s: failed to map library noload=%{public}d errno=%{public}d",
5386			task->name, noload, errno);
5387		error("Error loading library %s: failed to map library noload=%d errno=%d", task->name, noload, errno);
5388		if (runtime) {
5389			longjmp(*rtld_fail, 1);
5390		}
5391		return;
5392	};
5393
5394	/* Avoid the danger of getting two versions of libc mapped into the
5395	 * same process when an absolute pathname was used. The symbols
5396	 * checked are chosen to catch both musl and glibc, and to avoid
5397	 * false positives from interposition-hack libraries. */
5398	decode_dyn(task->p);
5399	if (find_sym(task->p, "__libc_start_main", 1).sym &&
5400		find_sym(task->p, "stdin", 1).sym) {
5401		do_dlclose(task->p);
5402		task->p = NULL;
5403		free((void*)task->name);
5404		task->name = ld_strdup("libc.so");
5405		task->check_inherited = true;
5406		if (!load_library_header(task)) {
5407			LD_LOGE("Error loading library %{public}s: failed to load libc.so", task->name);
5408			error("Error loading library %s: failed to load libc.so", task->name);
5409			if (runtime) {
5410				longjmp(*rtld_fail, 1);
5411			}
5412		}
5413		return;
5414	}
5415	/* Past this point, if we haven't reached runtime yet, ldso has
5416	 * committed either to use the mapped library or to abort execution.
5417	 * Unmapping is not possible, so we can safely reclaim gaps. */
5418	if (!runtime) {
5419		reclaim_gaps(task->p);
5420	}
5421	task->p->runtime_loaded = runtime;
5422	if (runtime)
5423		task->p->by_dlopen = 1;
5424
5425	if (DL_FDPIC) {
5426		makefuncdescs(task->p);
5427	}
5428
5429	if (ldd_mode) {
5430		dprintf(1, "\t%s => %s (%p)\n", task->name, task->pathname, task->p->base);
5431	}
5432
5433#ifdef ENABLE_HWASAN
5434	if (libc.load_hook) {
5435		libc.load_hook((long unsigned int)task->p->base, task->p->phdr, task->p->phnum);
5436	}
5437#endif
5438}
5439
5440static void preload_direct_deps(struct dso *p, ns_t *namespace, struct loadtasks *tasks)
5441{
5442	size_t i, cnt = 0;
5443	if (p->deps) {
5444		return;
5445	}
5446	/* For head, all preloads are direct pseudo-dependencies.
5447	 * Count and include them now to avoid realloc later. */
5448	if (p == head) {
5449		for (struct dso *q = p->next; q; q = q->next) {
5450			cnt++;
5451		}
5452	}
5453	for (i = 0; p->dynv[i]; i += NEXT_DYNAMIC_INDEX) {
5454		if (p->dynv[i] == DT_NEEDED) {
5455			cnt++;
5456		}
5457	}
5458	/* Use builtin buffer for apps with no external deps, to
5459	 * preserve property of no runtime failure paths. */
5460	p->deps = (p == head && cnt < MIN_DEPS_COUNT) ? builtin_deps :
5461		calloc(cnt + 1, sizeof *p->deps);
5462	if (!p->deps) {
5463		LD_LOGE("Error loading dependencies for %{public}s", p->name);
5464		error("Error loading dependencies for %s", p->name);
5465		if (runtime) {
5466			longjmp(*rtld_fail, 1);
5467		}
5468	}
5469	cnt = 0;
5470	if (p == head) {
5471		for (struct dso *q = p->next; q; q = q->next) {
5472			p->deps[cnt++] = q;
5473		}
5474	}
5475	for (i = 0; p->dynv[i]; i += NEXT_DYNAMIC_INDEX) {
5476		if (p->dynv[i] != DT_NEEDED) {
5477			continue;
5478		}
5479		const char* dtneed_name = p->strings + p->dynv[i + 1];
5480		LD_LOGD("load_library %{public}s adding DT_NEEDED task %{public}s namespace(%{public}s)", p->name, dtneed_name, namespace->ns_name);
5481		struct loadtask *task = create_loadtask(dtneed_name, p, namespace, true);
5482		if (!task) {
5483			LD_LOGE("Error loading dependencies %{public}s : create load task failed", p->name);
5484			error("Error loading dependencies for %s : create load task failed", p->name);
5485			if (runtime) {
5486				longjmp(*rtld_fail, 1);
5487			}
5488			continue;
5489		}
5490		LD_LOGD("loading shared library %{public}s: (needed by %{public}s)", p->strings + p->dynv[i+1], p->name);
5491		if (!load_library_header(task)) {
5492			free_task(task);
5493			task = NULL;
5494			LD_LOGE("Error loading shared library %{public}s: (needed by %{public}s)",
5495				p->strings + p->dynv[i + 1],
5496				p->name);
5497			error("Error loading shared library %s: %m (needed by %s)",
5498				p->strings + p->dynv[i + 1], p->name);
5499			if (runtime) {
5500				longjmp(*rtld_fail, 1);
5501			}
5502			continue;
5503		}
5504		p->deps[cnt++] = task->p;
5505		if (task->isloaded) {
5506			free_task(task);
5507			task = NULL;
5508		} else {
5509			append_loadtasks(tasks, task);
5510		}
5511	}
5512	p->deps[cnt] = 0;
5513	p->ndeps_direct = cnt;
5514	for (i = 0; i < p->ndeps_direct; i++) {
5515		add_dso_parent(p->deps[i], p);
5516	}
5517}
5518
5519static void unmap_preloaded_sections(struct loadtasks *tasks)
5520{
5521	struct loadtask *task = NULL;
5522	for (size_t i = 0; i < tasks->length; i++) {
5523		task = get_loadtask(tasks, i);
5524		if (!task) {
5525			continue;
5526		}
5527		if (task->dyn_map_len) {
5528			munmap(task->dyn_map, task->dyn_map_len);
5529			task->dyn_map = NULL;
5530			task->dyn_map_len = 0;
5531			if (task->p) {
5532				task->p->dynv = NULL;
5533			}
5534		}
5535		if (task->str_map_len) {
5536			munmap(task->str_map, task->str_map_len);
5537			task->str_map = NULL;
5538			task->str_map_len = 0;
5539			if (task->p) {
5540				task->p->strings = NULL;
5541			}
5542		}
5543	}
5544}
5545
5546static void preload_deps(struct dso *p, struct loadtasks *tasks)
5547{
5548	if (p->deps) {
5549		return;
5550	}
5551	for (; p; p = p->next) {
5552		preload_direct_deps(p, p->namespace, tasks);
5553	}
5554}
5555
5556static void run_loadtasks(struct loadtasks *tasks, struct reserved_address_params *reserved_params)
5557{
5558	struct loadtask *task = NULL;
5559	bool reserved_address = false;
5560	for (size_t i = 0; i < tasks->length; i++) {
5561		task = get_loadtask(tasks, i);
5562		if (task) {
5563			if (reserved_params) {
5564				reserved_address = reserved_params->reserved_address_recursive || (reserved_params->target == task->p);
5565			}
5566			task_load_library(task, reserved_address ? reserved_params : NULL);
5567		}
5568	}
5569}
5570
5571UT_STATIC void assign_tls(struct dso *p)
5572{
5573	while (p) {
5574		if (p->tls.image) {
5575			tls_align = MAXP2(tls_align, p->tls.align);
5576#ifdef TLS_ABOVE_TP
5577			p->tls.offset = tls_offset + ((p->tls.align - 1) &
5578				(-tls_offset + (uintptr_t)p->tls.image));
5579			tls_offset = p->tls.offset + p->tls.size;
5580#else
5581			tls_offset += p->tls.size + p->tls.align - 1;
5582			tls_offset -= (tls_offset + (uintptr_t)p->tls.image)
5583				& (p->tls.align - 1);
5584			p->tls.offset = tls_offset;
5585#endif
5586			if (tls_tail) {
5587				tls_tail->next = &p->tls;
5588			} else {
5589				libc.tls_head = &p->tls;
5590			}
5591			tls_tail = &p->tls;
5592		}
5593
5594		p = p->next;
5595	}
5596}
5597
5598UT_STATIC void load_preload(char *s, ns_t *ns, struct loadtasks *tasks)
5599{
5600	int tmp;
5601	char *z;
5602
5603	struct loadtask *task = NULL;
5604	for (z = s; *z; s = z) {
5605		for (; *s && (isspace(*s) || *s == ':'); s++) {
5606			;
5607		}
5608		for (z = s; *z && !isspace(*z) && *z != ':'; z++) {
5609			;
5610		}
5611		tmp = *z;
5612		*z = 0;
5613		task = create_loadtask(s, NULL, ns, true);
5614		if (!task) {
5615			continue;
5616		}
5617		if (load_library_header(task)) {
5618			if (!task->isloaded) {
5619				append_loadtasks(tasks, task);
5620				task = NULL;
5621			}
5622		}
5623		if (task) {
5624			free_task(task);
5625		}
5626		*z = tmp;
5627	}
5628}
5629#endif
5630
5631static int serialize_gnu_relro(int fd, struct dso *dso, ssize_t *file_offset)
5632{
5633	ssize_t count = dso->relro_end - dso->relro_start;
5634	ssize_t offset = 0;
5635	while (count > 0) {
5636		ssize_t write_size = TEMP_FAILURE_RETRY(write(fd, laddr(dso, dso->relro_start + offset), count));
5637		if (-1 == write_size) {
5638			LD_LOGE("Error serializing relro %{public}s: failed to write GNU_RELRO", dso->name);
5639			return -1;
5640		}
5641		offset += write_size;
5642		count -= write_size;
5643	}
5644
5645	ssize_t size = dso->relro_end - dso->relro_start;
5646	void *map = mmap(
5647		laddr(dso, dso->relro_start),
5648		size,
5649		PROT_READ,
5650		MAP_PRIVATE | MAP_FIXED,
5651		fd,
5652		*file_offset);
5653	if (map == MAP_FAILED) {
5654		LD_LOGE("Error serializing relro %{public}s: failed to map GNU_RELRO", dso->name);
5655		return -1;
5656	}
5657	*file_offset += size;
5658	return 0;
5659}
5660
5661static int map_gnu_relro(int fd, struct dso *dso, ssize_t *file_offset)
5662{
5663	ssize_t ext_fd_file_size = 0;
5664	struct stat ext_fd_file_stat;
5665	if (TEMP_FAILURE_RETRY(fstat(fd, &ext_fd_file_stat)) != 0) {
5666		LD_LOGE("Error mapping relro %{public}s: failed to get file state", dso->name);
5667		return -1;
5668	}
5669	ext_fd_file_size = ext_fd_file_stat.st_size;
5670
5671	void *ext_temp_map = MAP_FAILED;
5672	ext_temp_map = mmap(NULL, ext_fd_file_size, PROT_READ, MAP_PRIVATE, fd, 0);
5673	if (ext_temp_map == MAP_FAILED) {
5674		LD_LOGE("Error mapping relro %{public}s: failed to map fd", dso->name);
5675		return -1;
5676	}
5677
5678	char *file_base = (char *)(ext_temp_map) + *file_offset;
5679	char *mem_base = (char *)(laddr(dso, dso->relro_start));
5680	ssize_t start_offset = 0;
5681	ssize_t size = dso->relro_end - dso->relro_start;
5682
5683	if (size > ext_fd_file_size - *file_offset) {
5684		LD_LOGE("Error mapping relro %{public}s: invalid file size", dso->name);
5685		return -1;
5686	}
5687	while (start_offset < size) {
5688		// Find start location.
5689		while (start_offset < size) {
5690			if (memcmp(mem_base + start_offset, file_base + start_offset, PAGE_SIZE) == 0) {
5691				break;
5692			}
5693			start_offset += PAGE_SIZE;
5694		}
5695
5696		// Find end location.
5697		ssize_t end_offset = start_offset;
5698		while (end_offset < size) {
5699			if (memcmp(mem_base + end_offset, file_base + end_offset, PAGE_SIZE) != 0) {
5700				break;
5701			}
5702			end_offset += PAGE_SIZE;
5703		}
5704
5705		// Map pages.
5706		ssize_t map_length = end_offset - start_offset;
5707		ssize_t map_offset = *file_offset + start_offset;
5708		if (map_length > 0) {
5709			void *map = mmap(
5710				mem_base + start_offset, map_length, PROT_READ, MAP_PRIVATE | MAP_FIXED, fd, map_offset);
5711			if (map == MAP_FAILED) {
5712				LD_LOGE("Error mapping relro %{public}s: failed to map GNU_RELRO", dso->name);
5713				munmap(ext_temp_map, ext_fd_file_size);
5714				return -1;
5715			}
5716		}
5717
5718		start_offset = end_offset;
5719	}
5720	*file_offset += size;
5721	munmap(ext_temp_map, ext_fd_file_size);
5722	return 0;
5723}
5724
5725static void handle_relro_sharing(struct dso *p, const dl_extinfo *extinfo, ssize_t *relro_fd_offset)
5726{
5727	if (extinfo == NULL) {
5728		return;
5729	}
5730	if (extinfo->flag & DL_EXT_WRITE_RELRO) {
5731		LD_LOGD("Serializing GNU_RELRO %{public}s", p->name);
5732		if (serialize_gnu_relro(extinfo->relro_fd, p, relro_fd_offset) < 0) {
5733			LD_LOGE("Error serializing GNU_RELRO %{public}s", p->name);
5734			error("Error serializing GNU_RELRO");
5735			if (runtime) longjmp(*rtld_fail, 1);
5736		}
5737	} else if (extinfo->flag & DL_EXT_USE_RELRO) {
5738		LD_LOGD("Mapping GNU_RELRO %{public}s", p->name);
5739		if (map_gnu_relro(extinfo->relro_fd, p, relro_fd_offset) < 0) {
5740			LD_LOGE("Error mapping GNU_RELRO %{public}s", p->name);
5741			error("Error mapping GNU_RELRO");
5742			if (runtime) longjmp(*rtld_fail, 1);
5743		}
5744	}
5745}
5746
5747static void set_bss_vma_name(char *path_name, void *addr, size_t zeromap_size)
5748{
5749	char so_bss_name[ANON_NAME_MAX_LEN];
5750	if (path_name == NULL) {
5751		snprintf(so_bss_name, ANON_NAME_MAX_LEN, ".bss");
5752	} else {
5753		char *t = strrchr(path_name, '/');
5754		if (t) {
5755			snprintf(so_bss_name, ANON_NAME_MAX_LEN, "%s.bss", ++t);
5756		} else {
5757			snprintf(so_bss_name, ANON_NAME_MAX_LEN, "%s.bss", path_name);
5758		}
5759	}
5760
5761	prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, addr, zeromap_size, so_bss_name);
5762}
5763
5764static void find_and_set_bss_name(struct dso *p)
5765{
5766	size_t  cnt;
5767	Phdr *ph = p->phdr;
5768	for (cnt = p->phnum; cnt--; ph = (void *)((char *)ph + p->phentsize)) {
5769		if (ph->p_type != PT_LOAD) continue;
5770		size_t seg_start = p->base + ph->p_vaddr;
5771		size_t seg_file_end = seg_start + ph->p_filesz + PAGE_SIZE - 1 & -PAGE_SIZE;
5772		size_t seg_max_addr = seg_start + ph->p_memsz + PAGE_SIZE - 1 & -PAGE_SIZE;
5773		size_t zeromap_size = seg_max_addr - seg_file_end;
5774		if (zeromap_size > 0 && (ph->p_flags & PF_W)) {
5775			set_bss_vma_name(p->name, (void *)seg_file_end, zeromap_size);
5776		}
5777	}
5778}
5779
5780static void sync_with_debugger(void)
5781{
5782	debug.ver = 1;
5783	debug.bp = dl_debug_state;
5784	debug.head = NULL;
5785	debug.base = ldso.base;
5786
5787	add_dso_info_to_debug_map(head);
5788
5789	debug.state = RT_CONSISTENT;
5790	_dl_debug_state();
5791}
5792
5793static void notify_addition_to_debugger(struct dso *p)
5794{
5795	debug.state = RT_ADD;
5796	_dl_debug_state();
5797
5798	add_dso_info_to_debug_map(p);
5799
5800	debug.state = RT_CONSISTENT;
5801	_dl_debug_state();
5802}
5803
5804static void notify_remove_to_debugger(struct dso *p)
5805{
5806	debug.state = RT_DELETE;
5807	_dl_debug_state();
5808
5809	remove_dso_info_from_debug_map(p);
5810
5811	debug.state = RT_CONSISTENT;
5812	_dl_debug_state();
5813}
5814
5815static void add_dso_info_to_debug_map(struct dso *p)
5816{
5817	for (struct dso *so = p; so != NULL; so = so->next) {
5818		struct dso_debug_info *debug_info = malloc(sizeof(struct dso_debug_info));
5819		if (debug_info == NULL) {
5820			LD_LOGE("malloc error! dso name: %{public}s.", so->name);
5821			continue;
5822		}
5823#if DL_FDPIC
5824		debug_info->loadmap = so->loadmap;
5825#else
5826		debug_info->base = so->base;
5827#endif
5828		debug_info->name = so->name;
5829		debug_info->dynv = so->dynv;
5830		if (debug.head == NULL) {
5831			debug_info->prev = NULL;
5832			debug_info->next = NULL;
5833			debug.head = debug_tail = debug_info;
5834		} else {
5835			debug_info->prev = debug_tail;
5836			debug_info->next = NULL;
5837			debug_tail->next = debug_info;
5838			debug_tail = debug_info;
5839		}
5840		so->debug_info = debug_info;
5841	}
5842}
5843
5844static void remove_dso_info_from_debug_map(struct dso *p)
5845{
5846	struct dso_debug_info *debug_info = p->debug_info;
5847	if (debug_info == debug_tail) {
5848		debug_tail = debug_tail->prev;
5849		debug_tail->next = NULL;
5850	} else {
5851		debug_info->next->prev = debug_info->prev;
5852		debug_info->prev->next = debug_info->next;
5853	}
5854	free(debug_info);
5855}
5856