make dynamic linker report all failures before exiting

before, only the first library that failed to load or symbol that
failed to resolve was reported, and then the dynamic linker
immediately exited. when attempting to fix a library compatibility
issue, this is about the worst possible behavior. now we print all
errors as they occur and exit at the very end if errors were
encountered.
This commit is contained in:
Rich Felker 2012-08-18 16:00:23 -04:00
parent 53de960d6f
commit 04109502c0
1 changed files with 6 additions and 2 deletions

View File

@ -76,6 +76,7 @@ static int rtld_used;
static int ssp_used; static int ssp_used;
static int runtime; static int runtime;
static int ldd_mode; static int ldd_mode;
static int ldso_fail;
static jmp_buf rtld_fail; static jmp_buf rtld_fail;
static pthread_rwlock_t lock; static pthread_rwlock_t lock;
static struct debug debug; static struct debug debug;
@ -171,7 +172,8 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
dso->name, name); dso->name, name);
if (runtime) longjmp(rtld_fail, 1); if (runtime) longjmp(rtld_fail, 1);
dprintf(2, "%s\n", errbuf); dprintf(2, "%s\n", errbuf);
_exit(127); ldso_fail = 1;
continue;
} }
sym_size = sym->st_size; sym_size = sym->st_size;
} else { } else {
@ -450,7 +452,8 @@ static void load_deps(struct dso *p)
p->strings + p->dynv[i+1], p->name); 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); dprintf(2, "%s\n", errbuf);
_exit(127); ldso_fail = 1;
continue;
} }
if (runtime) { if (runtime) {
tmp = realloc(*deps, sizeof(*tmp)*(ndeps+2)); tmp = realloc(*deps, sizeof(*tmp)*(ndeps+2));
@ -682,6 +685,7 @@ void *__dynlink(int argc, char **argv)
reloc_all(app->next); reloc_all(app->next);
reloc_all(app); reloc_all(app);
if (ldso_fail) _exit(127);
if (ldd_mode) _exit(0); if (ldd_mode) _exit(0);
/* Switch to runtime mode: any further failures in the dynamic /* Switch to runtime mode: any further failures in the dynamic