fix dlopen/dlsym regression opening libs already loaded at startup
authorRich Felker <dalias@aerifal.cx>
Tue, 21 Mar 2017 12:35:59 +0000 (08:35 -0400)
committerRich Felker <dalias@aerifal.cx>
Tue, 21 Mar 2017 12:39:37 +0000 (08:39 -0400)
commit 4ff234f6cba96403b5de6d29d48a59fd73252040 erroneously changed
the condition for running certain code at dlopen time to check whether
the library was already relocated rather than whether it already had
its deps[] table filled. this was out of concern over whether the code
under the conditional would be idempotent/safe to call on an
already-loaded libraries. however, I missed a consideration in the
opposite direction: if a library was loaded at program startup rather
than dlopen, its deps[] table was not yet allocated/filled, and
load_deps needs to be called at dlopen time in order for dlsym to be
able to perform dependency-order symbol lookups.

in order to avoid wasteful allocation of lazy-binding relocation
tables for libraries which were already loaded and relocated at
startup, the check for !p->relocated is not deleted entirely, but
moved to apply only to allocation of these dables.

ldso/dynlink.c

index 5361b84..d20dbd8 100644 (file)
@@ -1768,9 +1768,9 @@ void *dlopen(const char *file, int mode)
        }
 
        /* First load handling */
-       if (!p->relocated) {
+       if (!p->deps) {
                load_deps(p);
-               if ((mode & RTLD_LAZY)) {
+               if (!p->relocated && (mode & RTLD_LAZY)) {
                        prepare_lazy(p);
                        if (p->deps) for (i=0; p->deps[i]; i++)
                                if (!p->deps[i]->relocated)