void __init_ssp(size_t *);
void *__install_initial_tls(void *);
+void __init_libc(char **, char *);
static struct dso *head, *tail, *ldso, *fini_head;
static char *env_path, *sys_path, *r_path;
if (fd < 0 && env_path) fd = path_open(name, env_path, buf, sizeof buf);
if (fd < 0) {
if (!sys_path) {
- FILE *f = fopen(ETC_LDSO_PATH, "rbe");
+ char *prefix = 0;
+ size_t prefix_len;
+ if (ldso->name[0]=='/') {
+ char *s, *t, *z;
+ for (s=t=z=ldso->name; *s; s++)
+ if (*s=='/') z=t, t=s;
+ prefix_len = z-ldso->name;
+ if (prefix_len < PATH_MAX)
+ prefix = ldso->name;
+ }
+ if (!prefix) {
+ prefix = "";
+ prefix_len = 0;
+ }
+ char etc_ldso_path[prefix_len + 1
+ + sizeof "/etc/ld-musl-" LDSO_ARCH ".path"];
+ snprintf(etc_ldso_path, sizeof etc_ldso_path,
+ "%.*s/etc/ld-musl-" LDSO_ARCH ".path",
+ (int)prefix_len, prefix);
+ FILE *f = fopen(etc_ldso_path, "rbe");
if (f) {
if (getdelim(&sys_path, (size_t[1]){0}, 0, f) <= 0) {
free(sys_path);
for (p=fini_head; p; p=p->fini_next) {
if (!p->constructed) continue;
decode_vec(p->dynv, dyn, DYN_CNT);
- ((void (*)(void))(p->base + dyn[DT_FINI]))();
+ if (dyn[0] & (1<<DT_FINI_ARRAY)) {
+ size_t n = dyn[DT_FINI_ARRAYSZ]/sizeof(size_t);
+ size_t *fn = (size_t *)(p->base + dyn[DT_FINI_ARRAY])+n;
+ while (n--) ((void (*)(void))*--fn)();
+ }
+#ifndef NO_LEGACY_INITFINI
+ if (dyn[0] & (1<<DT_FINI))
+ ((void (*)(void))(p->base + dyn[DT_FINI]))();
+#endif
}
}
if (p->constructed) continue;
p->constructed = 1;
decode_vec(p->dynv, dyn, DYN_CNT);
- if (dyn[0] & (1<<DT_FINI)) {
+ if (dyn[0] & ((1<<DT_FINI) | (1<<DT_FINI_ARRAY))) {
p->fini_next = fini_head;
fini_head = p;
}
+#ifndef NO_LEGACY_INITFINI
if (dyn[0] & (1<<DT_INIT))
((void (*)(void))(p->base + dyn[DT_INIT]))();
+#endif
+ if (dyn[0] & (1<<DT_INIT_ARRAY)) {
+ size_t n = dyn[DT_INIT_ARRAYSZ]/sizeof(size_t);
+ size_t *fn = (void *)(p->base + dyn[DT_INIT_ARRAY]);
+ while (n--) ((void (*)(void))*fn++)();
+ }
if (!need_locking && libc.threads_minus_1) {
need_locking = 1;
pthread_mutex_lock(&init_fini_lock);
char *env_preload=0;
size_t vdso_base;
size_t *auxv;
+ char **envp = argv+argc+1;
/* Find aux vector just past environ[] */
for (i=argc+1; argv[i]; i++)
tls_align = MAXP2(tls_align, app->tls_align);
}
app->global = 1;
- app->constructed = 1;
decode_dyn(app);
/* Attach to vdso, if provided by the kernel */
_dl_debug_state();
if (ssp_used) __init_ssp((void *)aux[AT_RANDOM]);
-
- errno = 0;
- return (void *)aux[AT_ENTRY];
-}
-
-void __init_ldso_ctors(void)
-{
+ __init_libc(envp, argv[0]);
atexit(do_fini);
+ errno = 0;
do_init_fini(tail);
+
+ return (void *)aux[AT_ENTRY];
}
void *dlopen(const char *file, int mode)