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;
static int ldd_mode;
static int ldso_fail;
static int noload;
-static jmp_buf rtld_fail;
+static jmp_buf *rtld_fail;
static pthread_rwlock_t lock;
static struct debug debug;
static size_t tls_cnt, tls_offset, tls_align = 4*sizeof(size_t);
}
#define OK_TYPES (1<<STT_NOTYPE | 1<<STT_OBJECT | 1<<STT_FUNC | 1<<STT_COMMON | 1<<STT_TLS)
-#define OK_BINDS (1<<STB_GLOBAL | 1<<STB_WEAK)
+#define OK_BINDS (1<<STB_GLOBAL | 1<<STB_WEAK | 1<<STB_GNU_UNIQUE)
static struct symdef find_sym(struct dso *dso, const char *s, int need_def)
{
snprintf(errbuf, sizeof errbuf,
"Error relocating %s: %s: symbol not found",
dso->name, name);
- if (runtime) longjmp(rtld_fail, 1);
+ if (runtime) longjmp(*rtld_fail, 1);
dprintf(2, "%s\n", errbuf);
ldso_fail = 1;
continue;
snprintf(errbuf, sizeof errbuf,
"Error loading shared library %s: %m (needed by %s)",
p->strings + p->dynv[i+1], p->name);
- if (runtime) longjmp(rtld_fail, 1);
+ if (runtime) longjmp(*rtld_fail, 1);
dprintf(2, "%s\n", errbuf);
ldso_fail = 1;
continue;
}
if (runtime) {
tmp = realloc(*deps, sizeof(*tmp)*(ndeps+2));
- if (!tmp) longjmp(rtld_fail, 1);
+ if (!tmp) longjmp(*rtld_fail, 1);
tmp[ndeps++] = dep;
tmp[ndeps] = 0;
*deps = tmp;
decode_vec(p->dynv, dyn, DYN_CNT);
if (dyn[0] & (1<<DT_FINI_ARRAY)) {
size_t n = dyn[DT_FINI_ARRAYSZ]/sizeof(size_t);
- size_t *fn = (void *)(p->base + dyn[DT_FINI_ARRAY]);
- while (n--) ((void (*)(void))*fn++)();
+ 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
}
}
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]);
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)
size_t orig_tls_cnt, orig_tls_offset, orig_tls_align;
size_t i;
int cs;
+ jmp_buf jb;
if (!file) return head;
orig_tail = tail;
noload = mode & RTLD_NOLOAD;
- if (setjmp(rtld_fail)) {
+ rtld_fail = &jb;
+ if (setjmp(*rtld_fail)) {
/* Clean up anything new that was (partially) loaded */
if (p && p->deps) for (i=0; p->deps[i]; i++)
if (p->deps[i]->global < 0)