+ /* Initial dso chain consists only of the app. We temporarily
+ * append the dynamic linker/libc so we can relocate it, then
+ * restore the initial chain in preparation for loading third
+ * party libraries (preload/needed). */
+ head = tail = app;
+ libc = lib;
+ app->next = lib;
+ reloc_all(lib);
+ app->next = 0;
+
+ /* PAST THIS POINT, ALL LIBC INTERFACES ARE FULLY USABLE. */
+
+ /* Donate unused parts of app and library mapping to malloc */
+ reclaim_gaps(app->base, (void *)aux[AT_PHDR], aux[AT_PHENT], aux[AT_PHNUM]);
+ ehdr = (void *)lib->base;
+ reclaim_gaps(lib->base, (void *)(lib->base+ehdr->e_phoff),
+ ehdr->e_phentsize, ehdr->e_phnum);
+
+ /* Load preload/needed libraries, add their symbols to the global
+ * namespace, and perform all remaining relocations. The main
+ * program must be relocated LAST since it may contain copy
+ * relocations which depend on libraries' relocations. */
+ if (env_preload) load_preload(env_preload);
+ load_deps(app);
+ make_global(app);
+
+ /* Make an initial pass setting up TLS before performing relocs.
+ * This provides the TP-based offset of each DSO's TLS for
+ * use in TP-relative relocations. After relocations, we need
+ * to copy the TLS images again in case they had relocs. */
+ tls_size += sizeof(struct pthread) + 4*sizeof(size_t);
+ __libc.tls_size = tls_size;
+ __libc.tls_cnt = tls_cnt;
+ if (tls_cnt) {
+ struct dso *p;
+ void *mem = mmap(0, __libc.tls_size, PROT_READ|PROT_WRITE,
+ MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+ if (mem==MAP_FAILED ||
+ !__install_initial_tls(__copy_tls(mem, tls_cnt))) {
+ dprintf(2, "%s: Error getting %zu bytes thread-local storage: %m\n",
+ argv[0], tls_size);
+ _exit(127);
+ }
+ for (p=head; p; p=p->next) {
+ if (!p->tls_id) continue;
+ p->tls_offset = (char *)__pthread_self()
+ - (char *)__pthread_self()->dtv[p->tls_id];
+ }
+ }
+
+ reloc_all(app->next);
+ reloc_all(app);
+
+ /* The initial DTV is located at the base of the memory
+ * allocated for TLS. Repeat copying TLS to pick up relocs. */
+ if (tls_cnt) __copy_tls((void *)__pthread_self()->dtv, tls_cnt);
+
+ if (ldso_fail) _exit(127);
+ if (ldd_mode) _exit(0);
+
+ /* Switch to runtime mode: any further failures in the dynamic
+ * linker are a reportable failure rather than a fatal startup
+ * error. If the dynamic loader (dlopen) will not be used, free
+ * all memory used by the dynamic linker. */
+ runtime = 1;
+
+#ifndef DYNAMIC_IS_RO
+ for (i=0; app->dynv[i]; i+=2)
+ if (app->dynv[i]==DT_DEBUG)
+ app->dynv[i+1] = (size_t)&debug;
+#endif
+ debug.ver = 1;
+ debug.bp = _dl_debug_state;
+ debug.head = head;
+ debug.base = lib->base;
+ debug.state = 0;
+ _dl_debug_state();
+
+ if (ssp_used) __init_ssp(auxv);
+
+ do_init_fini(tail);
+